{
    "cells": [
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "# MSTICPy Pivot Functions\n",
                "\n",
                "## What are Pivot Functions?\n",
                "\n",
                "MSTICPy has a lot of functionality distributed across many classes and modules. \n",
                "However, there is no simple way to discover where these functions are and what types\n",
                "of data the function is relevant to.\n",
                "\n",
                "Pivot functions bring this functionality together grouped around Entities.\n",
                "\n",
                "Entities are representations real-world objects found commonly in CyberSec investigations.\n",
                "Some examples are: IpAddress, Host, Account, URL\n",
                "\n",
                "```python\n",
                ">>> IpAddress.util.ip_type(ip_str=\"157.53.1.1\"))\n",
                "ip \tresult\n",
                "157.53.1.1 \tPublic\n",
                "\n",
                ">>> IpAddress.util.whois(\"157.53.1.1\"))\n",
                "asn \tasn_cidr \tasn_country_code \tasn_date \tasn_description \tasn_registry \tnets \tnir \tquery \traw \traw_referral \treferral\n",
                "NA \tNA \tUS \t2015-04-01 \tNA \tarin \t[{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '... \tNone \t157.53.1.1 \tNone \tNone \tNone\n",
                "                                      \n",
                ">>> IpAddress.util.geoloc(value=\"157.53.1.1\"))\n",
                "CountryCode \tCountryName \tState \tCity \tLongitude \tLatitude \tAsn \tedges \tType \tAdditionalData \tIpAddress\n",
                "US \tUnited States \tNone \tNone \t-97.822 \t37.751 \tNone \t{} \tgeolocation \t{} \t157.53.1.1\n",
                "                                      \n",
                ">>> Host.MSSentinel.list_host_logons(host_name=\"VictimPc\")\n",
                "Account \tEventID \tTimeGenerated \tSourceComputerId \tComputer \tSubjectUserName \tSubjectDomainName\n",
                "NT AUTHORITY\\SYSTEM \t4624 \t2020-10-01 22:39:36.987000+00:00 \tf6638b82-98a5-4542-8bec-6bc0977f793f \tVictimPc.Contoso.Azure \tVictimPc$ \tCONTOSO\n",
                "NT AUTHORITY\\SYSTEM \t4624 \t2020-10-01 22:39:37.220000+00:00 \tf6638b82-98a5-4542-8bec-6bc0977f793f \tVictimPc.Contoso.Azure \tVictimPc\\$ \tCONTOSO\n",
                "NT AUTHORITY\\SYSTEM \t4624 \t2020-10-01 22:39:42.603000+00:00 \tf6638b82-98a5-4542-8bec-6bc0977f793f \tVictimPc.Contoso.Azure \tVictimPc\\$ \tCONTOSO\n",
                "\n",
                "```\n",
                "\n",
                "You can also chain pivot functions together to create a processing\n",
                "pipeline that does multiple operations on data:\n",
                "```python\n",
                ">>> (\n",
                "        suspicious_ips_df\n",
                "        # Lookup IPs at VT\n",
                "        .mp_pivot.run(IpAddress.ti.lookup_ipv4_VirusTotal, column=\"IPAddress\")\n",
                "        # Filter on high severity\n",
                "        .query(\"Severity == 'high'\")\n",
                "        .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\", join=\"left\")\n",
                "        # Query IPs that have login attempts\n",
                "        .mp_pivot.run(IpAddress.MSSentinel.list_aad_signins_for_ip, ip_address_list=\"Ioc\")\n",
                "        # Send the output of this to a plot\n",
                "        .mp_plot.timeline(\n",
                "            title=\"High Severity IPs with Logon attempts\",\n",
                "            source_columns=[\"UserPrincipalName\", \"IPAddress\", \"ClientAppUsed\", \"Location\"],\n",
                "            group_by=\"UserPrincipalName\"\n",
                "        )\n",
                "    )\n",
                "\n",
                "```\n",
                "\n",
                "> We'll see examples of how to do these pivoting queries later in the notebook.\n",
                "\n",
                "MSTICPy has had entity classes from the very early days but, until now, these\n",
                "have only been used sporadically in the rest of the package.\n",
                "\n",
                "The pivot functionality exposed operations relevant to a particular\n",
                "entity as methods of that entity. These operations could include:\n",
                "\n",
                "- Data queries\n",
                "- Threat intelligence lookups\n",
                "- Other data lookups such as GeoLocation or domain resolution\n",
                "- and other local functionality\n",
                "\n",
                "## What is Pivoting?\n",
                "\n",
                "The name comes from the common practice of Cyber investigators navigating\n",
                "between related entities. For example an entity/investigation chain might\n",
                "look like the following:\n",
                "\n",
                "\n",
                "| Step | Source             |  Operation              | Target             |\n",
                "| :--: | :----------------- | :-----------------      | :----------------- |\n",
                "| 1    | Alert              | Review alert       ->   | Source IP(A)       |\n",
                "| 2    | Source IP(A)       | Lookup TI          ->   | Related URLs       |\n",
                "|      |                    |                         | Malware names      |\n",
                "| 3    | URL                | Query web logs     ->   | Requesting hosts   |\n",
                "| 4    | Host               | Query host logons  ->   | Accounts           |\n",
                "\n",
                "\n",
                "At each step there are one or more directions that you can take to\n",
                "follow the chain of related indicators of activity in a possible attack.\n",
                "\n",
                "Bringing these functions into a few, well-known locations makes it easier to\n",
                "use MSTICPy to carry out this common pivoting pattern in Jupyter notebooks."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "---\n",
                "\n",
                "## Getting started"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 5,
            "metadata": {},
            "outputs": [],
            "source": [
                "import msticpy as mp\n",
                "mp.init_notebook();"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "The pivoting subsystem will automatically load functions from\n",
                "*MSTICPy* that do not need any authentication.\n",
                "\n",
                "This is the case with providers such as Threat Intelligence (TILookup) and GeoIP.\n",
                "If not initialized before running `init_notebook`, they will be loaded with\n",
                "the defaults as specified in your *msticpyconfig.yaml*.\n",
                "\n",
                "For query providers, pivot functions are added dynamically as\n",
                "you connect/authenticate to the data provider."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### What happens at initialization?\n",
                "\n",
                "- TI provider is loaded and entity-specific lookups (e.g. IP, Url, File)\n",
                "  are added as pivot functions\n",
                "- Miscellaneous Msticpy functions and classes (e.g. GeoIP, IpType,\n",
                "  Domain utils) are added as pivot functions to the appropriate entity.\n",
                "\n",
                "You can add custom functions as pivot functions by creating a\n",
                "registration template and importing the function.\n",
                "Details of this are covered later in the document."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Load one or more data providers"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 2,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "Please wait. Loading Kqlmagic extension...done\n",
                        "Connecting... "
                    ]
                },
                {
                    "data": {
                        "text/html": [
                            "<!DOCTYPE html>\n",
                            "            <html><body>\n",
                            "            <div style=''>\n",
                            "            <a href='http://127.0.0.1:22514/webbrowser?url=http%3A//127.0.0.1%3A22514/files/.kqlmagic/temp_files/132684uGuO5WtMGspQ/popup__8ecf8077-cf51-4820-aadd-14040956f35d_at_loganalytics_schema.html%3Fkernelid%3D132684uGuO5WtMGspQ&kernelid=132684uGuO5WtMGspQ' style='padding: 2px 6px 2px 6px; color: #333333; background-color: #EEEEEE; border-top: 1px solid #CCCCCC; border-right: 1px solid #333333; border-bottom: 1px solid #333333; border-left: 1px solid #CCCCCC' target='popup__8ecf8077-cf51-4820-aadd-14040956f35d_at_loganalytics_schema'>popup schema 8ecf8077-cf51-4820-aadd-14040956f35d@loganalytics</a>\n",
                            "            </div>\n",
                            "            </body></html>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "connected\n"
                    ]
                }
            ],
            "source": [
                "az_provider = QueryProvider(\"MSSentinel\")\n",
                "az_provider.connect(workspace=\"Default\")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Pivot function list\n",
                "\n",
                "You can view the pivot functions loaded for\n",
                "an entity. Note that because we've loaded an\n",
                "MS Sentinel query provider a subset of the queries\n",
                "(those that have a `host_name` parameter) are\n",
                "also loaded.\n",
                "\n",
                "> Note entity classes are also automatically imported\n",
                "> by `init_notebook`, so you do not need to import\n",
                "> them manually."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 3,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "['MSSentinel.VMComputer_vmcomputer',\n",
                            " 'MSSentinel.auditd_auditd_all',\n",
                            " 'MSSentinel.az_nsg_interface',\n",
                            " 'MSSentinel.az_nsg_net_flows',\n",
                            " 'MSSentinel.az_nsg_net_flows_depr',\n",
                            " 'MSSentinel.heartbeat',\n",
                            " 'MSSentinel.heartbeat_for_host_depr',\n",
                            " 'MSSentinel.sec_alerts',\n",
                            " 'MSSentinel.sent_bookmarks',\n",
                            " 'MSSentinel.syslog_all_syslog',\n",
                            " 'MSSentinel.syslog_cron_activity',\n",
                            " 'MSSentinel.syslog_logon_failures',\n",
                            " 'MSSentinel.syslog_logons',\n",
                            " 'MSSentinel.syslog_squid_activity',\n",
                            " 'MSSentinel.syslog_sudo_activity',\n",
                            " 'MSSentinel.syslog_user_group_activity',\n",
                            " 'MSSentinel.syslog_user_logon',\n",
                            " 'MSSentinel.wevt_all_events',\n",
                            " 'MSSentinel.wevt_events_by_id',\n",
                            " 'MSSentinel.wevt_get_process_tree',\n",
                            " 'MSSentinel.wevt_list_other_events',\n",
                            " 'MSSentinel.wevt_logon_attempts',\n",
                            " 'MSSentinel.wevt_logon_failures',\n",
                            " 'MSSentinel.wevt_logon_session',\n",
                            " 'MSSentinel.wevt_logons',\n",
                            " 'MSSentinel.wevt_parent_process',\n",
                            " 'MSSentinel.wevt_process_session',\n",
                            " 'MSSentinel.wevt_processes',\n",
                            " 'RiskIQ.articles',\n",
                            " 'RiskIQ.artifacts',\n",
                            " 'RiskIQ.certificates',\n",
                            " 'RiskIQ.components',\n",
                            " 'RiskIQ.cookies',\n",
                            " 'RiskIQ.hostpair_children',\n",
                            " 'RiskIQ.hostpair_parents',\n",
                            " 'RiskIQ.malware',\n",
                            " 'RiskIQ.projects',\n",
                            " 'RiskIQ.reputation',\n",
                            " 'RiskIQ.resolutions',\n",
                            " 'RiskIQ.summary',\n",
                            " 'RiskIQ.trackers',\n",
                            " 'RiskIQ.whois',\n",
                            " 'dns_is_resolvable',\n",
                            " 'dns_resolve',\n",
                            " 'util.dns_components',\n",
                            " 'util.dns_in_abuse_list',\n",
                            " 'util.dns_is_resolvable',\n",
                            " 'util.dns_resolve',\n",
                            " 'util.dns_validate_tld']"
                        ]
                    },
                    "execution_count": 3,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Host.pivots()"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### See the list of providers loaded by the Pivot class\n",
                "\n",
                "Notice that TILookup was loaded even though we did not create an instance of TILookup beforehand."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 4,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "{'TILookup': <msticpy.context.tilookup.TILookup at 0x207f6fb7ac0>,\n",
                            " 'MSSentinel': <msticpy.data.core.data_providers.QueryProvider at 0x207f7132ee0>}"
                        ]
                    },
                    "execution_count": 4,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "mp.pivot.providers"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Pivot functions are grouped into containers\n",
                "\n",
                "Data queries are grouped into a container with the name of the data provider to which they belong.\n",
                "E.g. MSSentinel queries are in a container of that name, Spunk queries would be in a \"Splunk\" container.\n",
                "\n",
                "> Note: if you have multiple instances of a provider type\n",
                "> the name of the provider container will have a suffix\n",
                "> with the instance name (e.g. the Sentinel Workspace name).\n",
                "\n",
                "TI lookups are put into a \"ti\" container\n",
                "\n",
                "All other built-in functions are added to the \"other\" container.\n",
                "\n",
                "The containers themselves are callable and will return a list of their contents. \n",
                "Containers are also iterable - each iteration returns a tuple (pair) of name/function values.\n",
                "\n",
                "In notebooks/IPython you can also use tab completion to get to the right function."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "You can pass a substring to the `pivots` (or `get_pivot_list`) function"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 7,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "['MSSentinel.syslog_logon_failures',\n",
                            " 'MSSentinel.syslog_logons',\n",
                            " 'MSSentinel.syslog_user_logon',\n",
                            " 'MSSentinel.wevt_logon_attempts',\n",
                            " 'MSSentinel.wevt_logon_failures',\n",
                            " 'MSSentinel.wevt_logon_session',\n",
                            " 'MSSentinel.wevt_logons']"
                        ]
                    },
                    "execution_count": 7,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Host.pivots(\"logon\")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Using the Pivot Browser\n",
                "\n",
                "Pivot also has a utility that allows you to browse entities and the \n",
                "pivot functions attached to them. You can search for functions with\n",
                "desired keywords, view help for the specific function and copy the function\n",
                "signature to paste into a code cell.\n"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 8,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "application/vnd.jupyter.widget-view+json": {
                            "model_id": "57bc3a3465d048f4a59d1bf27f235b36",
                            "version_major": 2,
                            "version_minor": 0
                        },
                        "text/plain": [
                            "VBox(children=(HBox(children=(VBox(children=(HTML(value='<b>Entities</b>'), Select(description='entity', layou…"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "Pivot.browse()"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Running a pivot function\n",
                "\n",
                "Pivot functions have flexible input types. They can be used with the following types of parameters:\n",
                "\n",
                "- entity instances (e.g. where you have an IpAddress entity with a populated address field)\n",
                "- single values (e.g. a DNS domain name)\n",
                "- lists of values (e.g. a list of IpAddresses)\n",
                "- pandas DataFrames (where one or more of the columns contains the input parameter data)\n",
                "\n",
                "Pivot functions normally return results as a dataframe (although some complex functions such as Notebooklets\n",
                "can return composite results objects containing multiple dataframes and other object types.\n"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 27,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "List 'utility' pivot functions for IpAddress\n",
                        "\n",
                        "whois function\n",
                        "ip_type function\n",
                        "ip_rev_resolve function\n",
                        "geoloc function\n",
                        "geoloc_ips function\n",
                        "\n",
                        "-------------------------------\n",
                        "\n",
                        "Print help for a function - IpAddress.util.type\n",
                        "\n",
                        "Help on function get_ip_type in module msticpy.context.ip_utils:\n",
                        "\n",
                        "get_ip_type(ip: str = None, ip_str: str = None) -> str\n",
                        "    Validate value is an IP address and determine IPType category.\n",
                        "    \n",
                        "    (IPAddress category is e.g. Private/Public/Multicast).\n",
                        "    \n",
                        "    Parameters\n",
                        "    ----------\n",
                        "    ip : str\n",
                        "        The string of the IP Address\n",
                        "    ip_str : str\n",
                        "        The string of the IP Address - alias for `ip`\n",
                        "    \n",
                        "    Returns\n",
                        "    -------\n",
                        "    str\n",
                        "        Returns ip type string using ip address module\n",
                        "\n"
                    ]
                }
            ],
            "source": [
                "print(\"List 'utility' pivot functions for IpAddress\\n\")\n",
                "IpAddress.util()\n",
                "print()\n",
                "print(\"-------------------------------\\n\")\n",
                "print(\"Print help for a function - IpAddress.util.type\\n\")\n",
                "help(IpAddress.util.ip_type)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Parameter names\n",
                "- Positional parameter - If the function only accepts one parameter you can usually just supply it without a name - as a positional parameter (see first and third examples below)\n",
                "- Native parameter - You can also use the native parameter name - i.e. the name that the underlying function expects and that will be shown in the help(function) output\n",
                "- Generic parameter - You can also use the generic parameter name \"value\" in most cases.\n",
                "\n",
                "If in doubt, use help(entity.container.func) or entity.container.func?"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 14,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>10.1.1.1</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "         ip   result  src_row_index\n",
                            "0  10.1.1.1  Private              0"
                        ]
                    },
                    "execution_count": 14,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "IpAddress.util.ip_type(\"10.1.1.1\")"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 15,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>10.1.1.1</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "         ip   result  src_row_index\n",
                            "0  10.1.1.1  Private              0"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>157.53.1.1</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "           ip  result  src_row_index\n",
                            "0  157.53.1.1  Public              0"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>asn</th>\n",
                            "      <th>asn_cidr</th>\n",
                            "      <th>asn_country_code</th>\n",
                            "      <th>asn_date</th>\n",
                            "      <th>asn_description</th>\n",
                            "      <th>asn_registry</th>\n",
                            "      <th>nets</th>\n",
                            "      <th>nir</th>\n",
                            "      <th>query</th>\n",
                            "      <th>raw</th>\n",
                            "      <th>raw_referral</th>\n",
                            "      <th>referral</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>NA</td>\n",
                            "      <td>NA</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2015-04-01</td>\n",
                            "      <td>NA</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>[{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>157.53.1.1</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "  asn asn_cidr asn_country_code    asn_date asn_description asn_registry  \\\n",
                            "0  NA       NA               US  2015-04-01              NA         arin   \n",
                            "\n",
                            "                                                                                                  nets  \\\n",
                            "0  [{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '...   \n",
                            "\n",
                            "    nir       query   raw raw_referral referral  \n",
                            "0  None  157.53.1.1  None         None     None  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>CountryCode</th>\n",
                            "      <th>CountryName</th>\n",
                            "      <th>Longitude</th>\n",
                            "      <th>Latitude</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>IpAddress</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-97.822</td>\n",
                            "      <td>37.751</td>\n",
                            "      <td>2022-06-08 19:38:16.207819</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>157.53.1.1</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "  CountryCode    CountryName  Longitude  Latitude              TimeGenerated  \\\n",
                            "0          US  United States    -97.822    37.751 2022-06-08 19:38:16.207819   \n",
                            "\n",
                            "          Type   IpAddress  \n",
                            "0  geolocation  157.53.1.1  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "display(IpAddress.util.ip_type(\"10.1.1.1\"))\n",
                "display(IpAddress.util.ip_type(ip_str=\"157.53.1.1\"))\n",
                "display(IpAddress.util.whois(\"157.53.1.1\"))\n",
                "display(IpAddress.util.geoloc(value=\"157.53.1.1\"))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Using an entity as a parameter\n",
                "\n",
                "Behind the scenes the Pivot api is using a mapping of\n",
                "entity attributes to supply the right value to the function parameter."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 16,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>10.1.1.1</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "         ip   result  src_row_index\n",
                            "0  10.1.1.1  Private              0"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>157.53.1.1</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "           ip  result  src_row_index\n",
                            "0  157.53.1.1  Public              0"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>asn</th>\n",
                            "      <th>asn_cidr</th>\n",
                            "      <th>asn_country_code</th>\n",
                            "      <th>asn_date</th>\n",
                            "      <th>asn_description</th>\n",
                            "      <th>asn_registry</th>\n",
                            "      <th>nets</th>\n",
                            "      <th>nir</th>\n",
                            "      <th>query</th>\n",
                            "      <th>raw</th>\n",
                            "      <th>raw_referral</th>\n",
                            "      <th>referral</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>NA</td>\n",
                            "      <td>NA</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2015-04-01</td>\n",
                            "      <td>NA</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>[{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>157.53.1.1</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "  asn asn_cidr asn_country_code    asn_date asn_description asn_registry  \\\n",
                            "0  NA       NA               US  2015-04-01              NA         arin   \n",
                            "\n",
                            "                                                                                                  nets  \\\n",
                            "0  [{'cidr': '157.53.0.0/16', 'name': 'NETACTUATE-MDN-04', 'handle': 'NET-157-53-0-0-1', 'range': '...   \n",
                            "\n",
                            "    nir       query   raw raw_referral referral  \n",
                            "0  None  157.53.1.1  None         None     None  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>CountryCode</th>\n",
                            "      <th>CountryName</th>\n",
                            "      <th>Longitude</th>\n",
                            "      <th>Latitude</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>IpAddress</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-97.822</td>\n",
                            "      <td>37.751</td>\n",
                            "      <td>2022-06-08 19:38:19.432876</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>157.53.1.1</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "  CountryCode    CountryName  Longitude  Latitude              TimeGenerated  \\\n",
                            "0          US  United States    -97.822    37.751 2022-06-08 19:38:19.432876   \n",
                            "\n",
                            "          Type   IpAddress  \n",
                            "0  geolocation  157.53.1.1  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "ip1 = IpAddress(Address=\"10.1.1.1\")\n",
                "ip2 = IpAddress(Address=\"157.53.1.1\")\n",
                "\n",
                "display(IpAddress.util.ip_type(ip1))\n",
                "display(IpAddress.util.ip_type(ip2))\n",
                "display(IpAddress.util.whois(ip2))\n",
                "display(IpAddress.util.geoloc(ip2))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Using a list (or other iterable) as a parameter\n",
                "\n",
                "Many of the underlying functions will accept either single values or collections \n",
                "(usually in DataFrames) of values as input.\n",
                "Even in cases where the underlying function does not accept iterables as parameters, the\n",
                "Pivot library will usually be able to iterate through each value and collate the results\n",
                "to hand you back a single dataframe.\n",
                "\n",
                "> Note: there are some exceptions to this - usually where the underlying function<br>\n",
                "> is long-running or expensive and has opted not to accept iterated calls.<br>\n",
                "> Notebooklets are an example of these.<br>\n",
                "\n",
                "Where the function has multiple parameters you can supply a mixture of iterables and single values.\n",
                "\n",
                "- In this case, the single-valued parameters are re-used on each call, paired with the item\n",
                "  in the list(s) taken from the multi-valued parameters\n",
                "  \n",
                "You can also use multiple iterables for multiple parameters.\n",
                "- In this case the iterables *should* be the same length. \n",
                "  If they are different lengths the iterations stop after the shorted list/iterable is exhausted.\n",
                "  \n",
                "For example:\n",
                "```\n",
                "  list_1 = [1, 2, 3, 4]\n",
                "  list_2 = [\"a\", \"b\", \"c\"]\n",
                "  entity.util.func(p1=list_1, p2=list_2)\n",
                "```\n",
                "\n",
                "The function will execute with the pairings (1, \"a\"), (2, \"b\") and (3, \"c) - (4, \\_) will be ignored"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "---\n",
                "Use our magic function to convert pasted-in list to dataframe"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 17,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>AllExtIPs</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>172.217.15.99</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>40.85.232.64</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>11</th>\n",
                            "      <td>20.38.98.100</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>12</th>\n",
                            "      <td>23.96.64.84</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>13</th>\n",
                            "      <td>65.55.44.108</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>131.107.147.209</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>15</th>\n",
                            "      <td>10.0.3.4</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>16</th>\n",
                            "      <td>10.0.3.5</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>17</th>\n",
                            "      <td>13.82.152.48</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "          AllExtIPs\n",
                            "9     172.217.15.99\n",
                            "10     40.85.232.64\n",
                            "11     20.38.98.100\n",
                            "12      23.96.64.84\n",
                            "13     65.55.44.108\n",
                            "14  131.107.147.209\n",
                            "15         10.0.3.4\n",
                            "16         10.0.3.5\n",
                            "17     13.82.152.48"
                        ]
                    },
                    "execution_count": 17,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "%%txt2df --headers --name ip_df1\n",
                "AllExtIPs\n",
                "9, 172.217.15.99\n",
                "10, 40.85.232.64\n",
                "11, 20.38.98.100\n",
                "12, 23.96.64.84\n",
                "13, 65.55.44.108\n",
                "14, 131.107.147.209\n",
                "15, 10.0.3.4\n",
                "16, 10.0.3.5\n",
                "17, 13.82.152.48"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 18,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>4</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>5</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                ip   result  src_row_index\n",
                            "0      23.96.64.84   Public              0\n",
                            "1     65.55.44.108   Public              1\n",
                            "2  131.107.147.209   Public              2\n",
                            "3         10.0.3.4  Private              3\n",
                            "4         10.0.3.5  Private              4\n",
                            "5     13.82.152.48   Public              5"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>4</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>5</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                ip   result  src_row_index\n",
                            "0      23.96.64.84   Public              0\n",
                            "1     65.55.44.108   Public              1\n",
                            "2  131.107.147.209   Public              2\n",
                            "3         10.0.3.4  Private              3\n",
                            "4         10.0.3.5  Private              4\n",
                            "5     13.82.152.48   Public              5"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>nir</th>\n",
                            "      <th>asn_registry</th>\n",
                            "      <th>asn</th>\n",
                            "      <th>asn_cidr</th>\n",
                            "      <th>asn_country_code</th>\n",
                            "      <th>asn_date</th>\n",
                            "      <th>asn_description</th>\n",
                            "      <th>query</th>\n",
                            "      <th>nets</th>\n",
                            "      <th>raw</th>\n",
                            "      <th>referral</th>\n",
                            "      <th>raw_referral</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>23.96.0.0/14</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2013-06-18</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>[{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23....</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>65.52.0.0/14</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2001-02-14</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>[{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>3598</td>\n",
                            "      <td>131.107.0.0/16</td>\n",
                            "      <td>US</td>\n",
                            "      <td>1988-11-11</td>\n",
                            "      <td>MICROSOFT-CORP-AS, US</td>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>[{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>13.64.0.0/11</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2015-03-26</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>[{'cidr': '13.96.0.0/13, 13.104.0.0/14, 13.64.0.0/11', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "   nir asn_registry   asn        asn_cidr asn_country_code    asn_date  \\\n",
                            "0  NaN         arin  8075    23.96.0.0/14               US  2013-06-18   \n",
                            "1  NaN         arin  8075    65.52.0.0/14               US  2001-02-14   \n",
                            "2  NaN         arin  3598  131.107.0.0/16               US  1988-11-11   \n",
                            "3  NaN          NaN   NaN             NaN              NaN         NaN   \n",
                            "4  NaN          NaN   NaN             NaN              NaN         NaN   \n",
                            "5  NaN         arin  8075    13.64.0.0/11               US  2015-03-26   \n",
                            "\n",
                            "                   asn_description            query  \\\n",
                            "0  MICROSOFT-CORP-MSN-AS-BLOCK, US      23.96.64.84   \n",
                            "1  MICROSOFT-CORP-MSN-AS-BLOCK, US     65.55.44.108   \n",
                            "2            MICROSOFT-CORP-AS, US  131.107.147.209   \n",
                            "3                              NaN              NaN   \n",
                            "4                              NaN              NaN   \n",
                            "5  MICROSOFT-CORP-MSN-AS-BLOCK, US     13.82.152.48   \n",
                            "\n",
                            "                                                                                                  nets  \\\n",
                            "0  [{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23....   \n",
                            "1  [{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52...   \n",
                            "2  [{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10...   \n",
                            "3                                                                                                  NaN   \n",
                            "4                                                                                                  NaN   \n",
                            "5  [{'cidr': '13.96.0.0/13, 13.104.0.0/14, 13.64.0.0/11', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-...   \n",
                            "\n",
                            "   raw  referral  raw_referral  \n",
                            "0  NaN       NaN           NaN  \n",
                            "1  NaN       NaN           NaN  \n",
                            "2  NaN       NaN           NaN  \n",
                            "3  NaN       NaN           NaN  \n",
                            "4  NaN       NaN           NaN  \n",
                            "5  NaN       NaN           NaN  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>CountryCode</th>\n",
                            "      <th>CountryName</th>\n",
                            "      <th>State</th>\n",
                            "      <th>City</th>\n",
                            "      <th>Longitude</th>\n",
                            "      <th>Latitude</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>IpAddress</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 19:38:37.428898</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>23.96.64.84</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Boydton</td>\n",
                            "      <td>-78.3750</td>\n",
                            "      <td>36.6534</td>\n",
                            "      <td>2022-06-08 19:38:37.429901</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>65.55.44.108</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>Washington</td>\n",
                            "      <td>Redmond</td>\n",
                            "      <td>-122.1257</td>\n",
                            "      <td>47.6722</td>\n",
                            "      <td>2022-06-08 19:38:37.429901</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>131.107.147.209</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>Private address</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>location unknown</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>2022-06-08 19:38:37.429901</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>10.0.3.4</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>Private address</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>location unknown</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>2022-06-08 19:38:37.429901</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>10.0.3.5</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 19:38:37.430901</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>13.82.152.48</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "  CountryCode      CountryName       State              City  Longitude  \\\n",
                            "0          US    United States    Virginia      Tappahannock   -76.8545   \n",
                            "1          US    United States    Virginia           Boydton   -78.3750   \n",
                            "2          US    United States  Washington           Redmond  -122.1257   \n",
                            "3         NaN  Private address         NaN  location unknown        NaN   \n",
                            "4         NaN  Private address         NaN  location unknown        NaN   \n",
                            "5          US    United States    Virginia      Tappahannock   -76.8545   \n",
                            "\n",
                            "   Latitude              TimeGenerated         Type        IpAddress  \n",
                            "0   37.9273 2022-06-08 19:38:37.428898  geolocation      23.96.64.84  \n",
                            "1   36.6534 2022-06-08 19:38:37.429901  geolocation     65.55.44.108  \n",
                            "2   47.6722 2022-06-08 19:38:37.429901  geolocation  131.107.147.209  \n",
                            "3       NaN 2022-06-08 19:38:37.429901  geolocation         10.0.3.4  \n",
                            "4       NaN 2022-06-08 19:38:37.429901  geolocation         10.0.3.5  \n",
                            "5   37.9273 2022-06-08 19:38:37.430901  geolocation     13.82.152.48  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "ip_list1 = ip_df1.AllExtIPs.values[-6:]\n",
                "\n",
                "display(IpAddress.util.ip_type(ip_list1))\n",
                "display(IpAddress.util.ip_type(ip_str=list(ip_list1)))\n",
                "display(IpAddress.util.whois(value=tuple(ip_list1)))\n",
                "display(IpAddress.util.geoloc(ip_list1))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Using DataFrames as input\n",
                "\n",
                "Using a dataframe as input requires a slightly different syntax since you not\n",
                "only need to pass the dataframe as a parameter but also tell the function\n",
                "which column to use for input.\n",
                "\n",
                "To specify the column to use, you can use the name of the parameter that the\n",
                "underlying function expects or one of these generic names:\n",
                "\n",
                "- column\n",
                "- input_column\n",
                "- input_col\n",
                "- src_column\n",
                "- src_col\n",
                "\n",
                "> Note these generic names are not shown in the function help"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 19,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>172.217.15.99</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>40.85.232.64</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>20.38.98.100</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>4</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>5</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>6</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>7</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>8</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                ip   result  src_row_index\n",
                            "0    172.217.15.99   Public              0\n",
                            "1     40.85.232.64   Public              1\n",
                            "2     20.38.98.100   Public              2\n",
                            "3      23.96.64.84   Public              3\n",
                            "4     65.55.44.108   Public              4\n",
                            "5  131.107.147.209   Public              5\n",
                            "6         10.0.3.4  Private              6\n",
                            "7         10.0.3.5  Private              7\n",
                            "8     13.82.152.48   Public              8"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>src_row_index</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>172.217.15.99</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>40.85.232.64</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>20.38.98.100</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>4</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>5</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>6</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>Private</td>\n",
                            "      <td>7</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>8</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                ip   result  src_row_index\n",
                            "0    172.217.15.99   Public              0\n",
                            "1     40.85.232.64   Public              1\n",
                            "2     20.38.98.100   Public              2\n",
                            "3      23.96.64.84   Public              3\n",
                            "4     65.55.44.108   Public              4\n",
                            "5  131.107.147.209   Public              5\n",
                            "6         10.0.3.4  Private              6\n",
                            "7         10.0.3.5  Private              7\n",
                            "8     13.82.152.48   Public              8"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>nir</th>\n",
                            "      <th>asn_registry</th>\n",
                            "      <th>asn</th>\n",
                            "      <th>asn_cidr</th>\n",
                            "      <th>asn_country_code</th>\n",
                            "      <th>asn_date</th>\n",
                            "      <th>asn_description</th>\n",
                            "      <th>query</th>\n",
                            "      <th>nets</th>\n",
                            "      <th>raw</th>\n",
                            "      <th>referral</th>\n",
                            "      <th>raw_referral</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>15169</td>\n",
                            "      <td>172.217.15.0/24</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2012-04-16</td>\n",
                            "      <td>GOOGLE, US</td>\n",
                            "      <td>172.217.15.99</td>\n",
                            "      <td>[{'cidr': '172.217.0.0/16', 'name': 'GOOGLE', 'handle': 'NET-172-217-0-0-1', 'range': '172.217.0...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>40.80.0.0/12</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2015-02-23</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>40.85.232.64</td>\n",
                            "      <td>[{'cidr': '40.96.0.0/12, 40.74.0.0/15, 40.124.0.0/16, 40.80.0.0/12, 40.125.0.0/17, 40.112.0.0/13...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>11</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>20.36.0.0/14</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2017-10-18</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>20.38.98.100</td>\n",
                            "      <td>[{'cidr': '20.40.0.0/13, 20.33.0.0/16, 20.64.0.0/10, 20.128.0.0/16, 20.34.0.0/15, 20.36.0.0/14, ...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>12</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>23.96.0.0/14</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2013-06-18</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>[{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23....</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>13</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>65.52.0.0/14</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2001-02-14</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>[{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>3598</td>\n",
                            "      <td>131.107.0.0/16</td>\n",
                            "      <td>US</td>\n",
                            "      <td>1988-11-11</td>\n",
                            "      <td>MICROSOFT-CORP-AS, US</td>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>[{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>15</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>16</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>17</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>arin</td>\n",
                            "      <td>8075</td>\n",
                            "      <td>13.64.0.0/11</td>\n",
                            "      <td>US</td>\n",
                            "      <td>2015-03-26</td>\n",
                            "      <td>MICROSOFT-CORP-MSN-AS-BLOCK, US</td>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>[{'cidr': '13.96.0.0/13, 13.104.0.0/14, 13.64.0.0/11', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-...</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "    nir asn_registry    asn         asn_cidr asn_country_code    asn_date  \\\n",
                            "9   NaN         arin  15169  172.217.15.0/24               US  2012-04-16   \n",
                            "10  NaN         arin   8075     40.80.0.0/12               US  2015-02-23   \n",
                            "11  NaN         arin   8075     20.36.0.0/14               US  2017-10-18   \n",
                            "12  NaN         arin   8075     23.96.0.0/14               US  2013-06-18   \n",
                            "13  NaN         arin   8075     65.52.0.0/14               US  2001-02-14   \n",
                            "14  NaN         arin   3598   131.107.0.0/16               US  1988-11-11   \n",
                            "15  NaN          NaN    NaN              NaN              NaN         NaN   \n",
                            "16  NaN          NaN    NaN              NaN              NaN         NaN   \n",
                            "17  NaN         arin   8075     13.64.0.0/11               US  2015-03-26   \n",
                            "\n",
                            "                    asn_description            query  \\\n",
                            "9                        GOOGLE, US    172.217.15.99   \n",
                            "10  MICROSOFT-CORP-MSN-AS-BLOCK, US     40.85.232.64   \n",
                            "11  MICROSOFT-CORP-MSN-AS-BLOCK, US     20.38.98.100   \n",
                            "12  MICROSOFT-CORP-MSN-AS-BLOCK, US      23.96.64.84   \n",
                            "13  MICROSOFT-CORP-MSN-AS-BLOCK, US     65.55.44.108   \n",
                            "14            MICROSOFT-CORP-AS, US  131.107.147.209   \n",
                            "15                              NaN              NaN   \n",
                            "16                              NaN              NaN   \n",
                            "17  MICROSOFT-CORP-MSN-AS-BLOCK, US     13.82.152.48   \n",
                            "\n",
                            "                                                                                                   nets  \\\n",
                            "9   [{'cidr': '172.217.0.0/16', 'name': 'GOOGLE', 'handle': 'NET-172-217-0-0-1', 'range': '172.217.0...   \n",
                            "10  [{'cidr': '40.96.0.0/12, 40.74.0.0/15, 40.124.0.0/16, 40.80.0.0/12, 40.125.0.0/17, 40.112.0.0/13...   \n",
                            "11  [{'cidr': '20.40.0.0/13, 20.33.0.0/16, 20.64.0.0/10, 20.128.0.0/16, 20.34.0.0/15, 20.36.0.0/14, ...   \n",
                            "12  [{'cidr': '23.96.0.0/13', 'name': 'MSFT', 'handle': 'NET-23-96-0-0-1', 'range': '23.96.0.0 - 23....   \n",
                            "13  [{'cidr': '65.52.0.0/14', 'name': 'MICROSOFT-1BLK', 'handle': 'NET-65-52-0-0-1', 'range': '65.52...   \n",
                            "14  [{'cidr': '131.107.0.0/16', 'name': 'MICROSOFT', 'handle': 'NET-131-107-0-0-1', 'range': '131.10...   \n",
                            "15                                                                                                  NaN   \n",
                            "16                                                                                                  NaN   \n",
                            "17  [{'cidr': '13.96.0.0/13, 13.104.0.0/14, 13.64.0.0/11', 'name': 'MSFT', 'handle': 'NET-13-64-0-0-...   \n",
                            "\n",
                            "    raw  referral  raw_referral  \n",
                            "9   NaN       NaN           NaN  \n",
                            "10  NaN       NaN           NaN  \n",
                            "11  NaN       NaN           NaN  \n",
                            "12  NaN       NaN           NaN  \n",
                            "13  NaN       NaN           NaN  \n",
                            "14  NaN       NaN           NaN  \n",
                            "15  NaN       NaN           NaN  \n",
                            "16  NaN       NaN           NaN  \n",
                            "17  NaN       NaN           NaN  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>CountryCode</th>\n",
                            "      <th>CountryName</th>\n",
                            "      <th>Longitude</th>\n",
                            "      <th>Latitude</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>IpAddress</th>\n",
                            "      <th>State</th>\n",
                            "      <th>City</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-97.8220</td>\n",
                            "      <td>37.7510</td>\n",
                            "      <td>2022-06-08 19:38:44.907125</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>172.217.15.99</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>CA</td>\n",
                            "      <td>Canada</td>\n",
                            "      <td>-79.3623</td>\n",
                            "      <td>43.6547</td>\n",
                            "      <td>2022-06-08 19:38:44.907125</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>40.85.232.64</td>\n",
                            "      <td>Ontario</td>\n",
                            "      <td>Toronto</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 19:38:44.907125</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>20.38.98.100</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 19:38:44.908124</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-78.3750</td>\n",
                            "      <td>36.6534</td>\n",
                            "      <td>2022-06-08 19:38:44.908124</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Boydton</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-122.1257</td>\n",
                            "      <td>47.6722</td>\n",
                            "      <td>2022-06-08 19:38:44.909124</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>Washington</td>\n",
                            "      <td>Redmond</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>Private address</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>2022-06-08 19:38:44.909124</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>location unknown</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>NaN</td>\n",
                            "      <td>Private address</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>2022-06-08 19:38:44.909124</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>location unknown</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 19:38:44.909124</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "  CountryCode      CountryName  Longitude  Latitude  \\\n",
                            "0          US    United States   -97.8220   37.7510   \n",
                            "1          CA           Canada   -79.3623   43.6547   \n",
                            "2          US    United States   -76.8545   37.9273   \n",
                            "3          US    United States   -76.8545   37.9273   \n",
                            "4          US    United States   -78.3750   36.6534   \n",
                            "5          US    United States  -122.1257   47.6722   \n",
                            "6         NaN  Private address        NaN       NaN   \n",
                            "7         NaN  Private address        NaN       NaN   \n",
                            "8          US    United States   -76.8545   37.9273   \n",
                            "\n",
                            "               TimeGenerated         Type        IpAddress       State  \\\n",
                            "0 2022-06-08 19:38:44.907125  geolocation    172.217.15.99         NaN   \n",
                            "1 2022-06-08 19:38:44.907125  geolocation     40.85.232.64     Ontario   \n",
                            "2 2022-06-08 19:38:44.907125  geolocation     20.38.98.100    Virginia   \n",
                            "3 2022-06-08 19:38:44.908124  geolocation      23.96.64.84    Virginia   \n",
                            "4 2022-06-08 19:38:44.908124  geolocation     65.55.44.108    Virginia   \n",
                            "5 2022-06-08 19:38:44.909124  geolocation  131.107.147.209  Washington   \n",
                            "6 2022-06-08 19:38:44.909124  geolocation         10.0.3.4         NaN   \n",
                            "7 2022-06-08 19:38:44.909124  geolocation         10.0.3.5         NaN   \n",
                            "8 2022-06-08 19:38:44.909124  geolocation     13.82.152.48    Virginia   \n",
                            "\n",
                            "               City  \n",
                            "0               NaN  \n",
                            "1           Toronto  \n",
                            "2      Tappahannock  \n",
                            "3      Tappahannock  \n",
                            "4           Boydton  \n",
                            "5           Redmond  \n",
                            "6  location unknown  \n",
                            "7  location unknown  \n",
                            "8      Tappahannock  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "display(IpAddress.util.ip_type(data=ip_df1, input_col=\"AllExtIPs\"))\n",
                "display(IpAddress.util.ip_type(data=ip_df1, ip=\"AllExtIPs\"))\n",
                "display(IpAddress.util.whois(data=ip_df1, column=\"AllExtIPs\"))\n",
                "display(IpAddress.util.geoloc(data=ip_df1, src_col=\"AllExtIPs\"))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Joining input to output data\n",
                "\n",
                "You might want to return a data set that is joined to your input set.\n",
                "To do that use the \"join\" parameter.\n",
                "\n",
                "The value of join can be:\n",
                "- inner\n",
                "- left\n",
                "- right\n",
                "- outer\n",
                "\n",
                "To preserve all rows from the input, use a \"left\" join.\n",
                "To keep only rows that have a valid result from the function use \"inner\" or \"right\"\n",
                "\n",
                "> Note while most functions only return a single output row for each input row<br>\n",
                "> some return multiple rows. Be cautious using \"outer\" in these cases."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 28,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>AllExtIPs</th>\n",
                            "      <th>CountryCode</th>\n",
                            "      <th>CountryName</th>\n",
                            "      <th>Longitude</th>\n",
                            "      <th>Latitude</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>IpAddress</th>\n",
                            "      <th>State</th>\n",
                            "      <th>City</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>172.217.15.99</td>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-97.8220</td>\n",
                            "      <td>37.7510</td>\n",
                            "      <td>2022-06-08 23:18:07.276418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>172.217.15.99</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>40.85.232.64</td>\n",
                            "      <td>CA</td>\n",
                            "      <td>Canada</td>\n",
                            "      <td>-79.3623</td>\n",
                            "      <td>43.6547</td>\n",
                            "      <td>2022-06-08 23:18:07.277418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>40.85.232.64</td>\n",
                            "      <td>Ontario</td>\n",
                            "      <td>Toronto</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>20.38.98.100</td>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 23:18:07.277418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>20.38.98.100</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 23:18:07.277418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>23.96.64.84</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-78.3750</td>\n",
                            "      <td>36.6534</td>\n",
                            "      <td>2022-06-08 23:18:07.278418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>65.55.44.108</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Boydton</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-122.1257</td>\n",
                            "      <td>47.6722</td>\n",
                            "      <td>2022-06-08 23:18:07.278418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>131.107.147.209</td>\n",
                            "      <td>Washington</td>\n",
                            "      <td>Redmond</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>Private address</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>2022-06-08 23:18:07.278418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>10.0.3.4</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>location unknown</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>Private address</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>2022-06-08 23:18:07.278418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>10.0.3.5</td>\n",
                            "      <td>NaN</td>\n",
                            "      <td>location unknown</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>US</td>\n",
                            "      <td>United States</td>\n",
                            "      <td>-76.8545</td>\n",
                            "      <td>37.9273</td>\n",
                            "      <td>2022-06-08 23:18:07.278418</td>\n",
                            "      <td>geolocation</td>\n",
                            "      <td>13.82.152.48</td>\n",
                            "      <td>Virginia</td>\n",
                            "      <td>Tappahannock</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "         AllExtIPs CountryCode      CountryName  Longitude  Latitude  \\\n",
                            "0    172.217.15.99          US    United States   -97.8220   37.7510   \n",
                            "1     40.85.232.64          CA           Canada   -79.3623   43.6547   \n",
                            "2     20.38.98.100          US    United States   -76.8545   37.9273   \n",
                            "3      23.96.64.84          US    United States   -76.8545   37.9273   \n",
                            "4     65.55.44.108          US    United States   -78.3750   36.6534   \n",
                            "5  131.107.147.209          US    United States  -122.1257   47.6722   \n",
                            "6         10.0.3.4         NaN  Private address        NaN       NaN   \n",
                            "7         10.0.3.5         NaN  Private address        NaN       NaN   \n",
                            "8     13.82.152.48          US    United States   -76.8545   37.9273   \n",
                            "\n",
                            "               TimeGenerated         Type        IpAddress       State  \\\n",
                            "0 2022-06-08 23:18:07.276418  geolocation    172.217.15.99         NaN   \n",
                            "1 2022-06-08 23:18:07.277418  geolocation     40.85.232.64     Ontario   \n",
                            "2 2022-06-08 23:18:07.277418  geolocation     20.38.98.100    Virginia   \n",
                            "3 2022-06-08 23:18:07.277418  geolocation      23.96.64.84    Virginia   \n",
                            "4 2022-06-08 23:18:07.278418  geolocation     65.55.44.108    Virginia   \n",
                            "5 2022-06-08 23:18:07.278418  geolocation  131.107.147.209  Washington   \n",
                            "6 2022-06-08 23:18:07.278418  geolocation         10.0.3.4         NaN   \n",
                            "7 2022-06-08 23:18:07.278418  geolocation         10.0.3.5         NaN   \n",
                            "8 2022-06-08 23:18:07.278418  geolocation     13.82.152.48    Virginia   \n",
                            "\n",
                            "               City  \n",
                            "0               NaN  \n",
                            "1           Toronto  \n",
                            "2      Tappahannock  \n",
                            "3      Tappahannock  \n",
                            "4           Boydton  \n",
                            "5           Redmond  \n",
                            "6  location unknown  \n",
                            "7  location unknown  \n",
                            "8      Tappahannock  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "display(IpAddress.util.geoloc(data=ip_df1, src_col=\"AllExtIPs\", join=\"left\"))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## DataQuery Pivot functions\n",
                "\n",
                "A significant difference between the functions that we've seen so far\n",
                "and data query functions is that the latter **do not accept generic parameter names.**\n",
                "\n",
                "When you use a named parameter in a data query pivot, you must specify\n",
                "the name that the query function is expecting. If in doubt, use \"?\" prefix to show the function help.\n",
                "\n",
                "Example:\n",
                "```\n",
                "    Host.MSSentinel.list_host_events_by_id?\n",
                "```"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 32,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "Connecting... connected\n"
                    ]
                },
                {
                    "data": {
                        "text/html": [
                            "<!DOCTYPE html>\n",
                            "            <html><body>\n",
                            "            <div style=''>\n",
                            "            <b>FKAH67GNV</b>&nbsp;<a href='http://127.0.0.1:29841/webbrowser?url=http%3A//127.0.0.1%3A29841/files/.kqlmagic/temp_files/822246zXwYZm4GxSg/popup_devicelogin.html%3Fkernelid%3D822246zXwYZm4GxSg&kernelid=822246zXwYZm4GxSg' style='padding: 2px 6px 2px 6px; color: #333333; background-color: #EEEEEE; border-top: 1px solid #CCCCCC; border-right: 1px solid #333333; border-bottom: 1px solid #333333; border-left: 1px solid #CCCCCC' target='popup_verification_url'>Copy code to clipboard and authenticate</a>\n",
                            "            </div>\n",
                            "            </body></html>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<!DOCTYPE html>\n",
                            "                            <html><body><script>\n",
                            "\n",
                            "                                // close authentication window\n",
                            "                                if (kql_MagicUserCodeAuthWindow && kql_MagicUserCodeAuthWindow.opener != null && !kql_MagicUserCodeAuthWindow.closed) {\n",
                            "                                    kql_MagicUserCodeAuthWindow.close()\n",
                            "                                }\n",
                            "                                // TODO: make sure, you clear the right cell. BTW, not sure it is a must to do any clearing\n",
                            "\n",
                            "                                // clear output cell\n",
                            "                                Jupyter.notebook.clear_output(Jupyter.notebook.get_selected_index())\n",
                            "\n",
                            "                                // TODO: if in run all mode, move to last cell, otherwise move to next cell\n",
                            "                                // move to next cell\n",
                            "\n",
                            "                            </script></body></html>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "qry_prov2 = QueryProvider(\"MSSentinel\")\n",
                "qry_prov2.connect(workspace=\"CyberSecuritySOC\")"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 33,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "['MSSentinel.VMComputer_vmcomputer',\n",
                            " 'MSSentinel.auditd_auditd_all',\n",
                            " 'MSSentinel.az_nsg_interface',\n",
                            " 'MSSentinel.az_nsg_net_flows',\n",
                            " 'MSSentinel.az_nsg_net_flows_depr',\n",
                            " 'MSSentinel.heartbeat',\n",
                            " 'MSSentinel.heartbeat_for_host_depr',\n",
                            " 'MSSentinel.sec_alerts',\n",
                            " 'MSSentinel.sent_bookmarks',\n",
                            " 'MSSentinel.syslog_all_syslog',\n",
                            " 'MSSentinel.syslog_cron_activity',\n",
                            " 'MSSentinel.syslog_logon_failures',\n",
                            " 'MSSentinel.syslog_logons',\n",
                            " 'MSSentinel.syslog_squid_activity',\n",
                            " 'MSSentinel.syslog_sudo_activity',\n",
                            " 'MSSentinel.syslog_user_group_activity',\n",
                            " 'MSSentinel.syslog_user_logon',\n",
                            " 'MSSentinel.wevt_all_events',\n",
                            " 'MSSentinel.wevt_events_by_id',\n",
                            " 'MSSentinel.wevt_get_process_tree',\n",
                            " 'MSSentinel.wevt_list_other_events',\n",
                            " 'MSSentinel.wevt_logon_attempts',\n",
                            " 'MSSentinel.wevt_logon_failures',\n",
                            " 'MSSentinel.wevt_logon_session',\n",
                            " 'MSSentinel.wevt_logons',\n",
                            " 'MSSentinel.wevt_parent_process',\n",
                            " 'MSSentinel.wevt_process_session',\n",
                            " 'MSSentinel.wevt_processes',\n",
                            " 'MSSentinel_cybersecuritysoc.VMComputer_vmcomputer',\n",
                            " 'MSSentinel_cybersecuritysoc.auditd_auditd_all',\n",
                            " 'MSSentinel_cybersecuritysoc.az_nsg_interface',\n",
                            " 'MSSentinel_cybersecuritysoc.az_nsg_net_flows',\n",
                            " 'MSSentinel_cybersecuritysoc.az_nsg_net_flows_depr',\n",
                            " 'MSSentinel_cybersecuritysoc.heartbeat',\n",
                            " 'MSSentinel_cybersecuritysoc.heartbeat_for_host_depr',\n",
                            " 'MSSentinel_cybersecuritysoc.sec_alerts',\n",
                            " 'MSSentinel_cybersecuritysoc.sent_bookmarks',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_all_syslog',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_cron_activity',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_logon_failures',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_logons',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_squid_activity',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_sudo_activity',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_user_group_activity',\n",
                            " 'MSSentinel_cybersecuritysoc.syslog_user_logon',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_all_events',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_events_by_id',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_get_process_tree',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_list_other_events',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_logon_attempts',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_logon_failures',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_logon_session',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_logons',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_parent_process',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_process_session',\n",
                            " 'MSSentinel_cybersecuritysoc.wevt_processes',\n",
                            " 'RiskIQ.articles',\n",
                            " 'RiskIQ.artifacts',\n",
                            " 'RiskIQ.certificates',\n",
                            " 'RiskIQ.components',\n",
                            " 'RiskIQ.cookies',\n",
                            " 'RiskIQ.hostpair_children',\n",
                            " 'RiskIQ.hostpair_parents',\n",
                            " 'RiskIQ.malware',\n",
                            " 'RiskIQ.projects',\n",
                            " 'RiskIQ.reputation',\n",
                            " 'RiskIQ.resolutions',\n",
                            " 'RiskIQ.summary',\n",
                            " 'RiskIQ.trackers',\n",
                            " 'RiskIQ.whois',\n",
                            " 'dns_is_resolvable',\n",
                            " 'dns_resolve',\n",
                            " 'util.dns_components',\n",
                            " 'util.dns_in_abuse_list',\n",
                            " 'util.dns_is_resolvable',\n",
                            " 'util.dns_resolve',\n",
                            " 'util.dns_validate_tld']"
                        ]
                    },
                    "execution_count": 33,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Host.pivots()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 30,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "['MSSentinel.VMComputer_vmcomputer',\n",
                            " 'MSSentinel.auditd_auditd_all',\n",
                            " 'MSSentinel.az_nsg_interface',\n",
                            " 'MSSentinel.az_nsg_net_flows',\n",
                            " 'MSSentinel.az_nsg_net_flows_depr',\n",
                            " 'MSSentinel.heartbeat',\n",
                            " 'MSSentinel.heartbeat_for_host_depr',\n",
                            " 'MSSentinel.sec_alerts',\n",
                            " 'MSSentinel.sent_bookmarks',\n",
                            " 'MSSentinel.syslog_all_syslog']"
                        ]
                    },
                    "execution_count": 30,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Host.pivots()[:10]"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Setting time parameters for queries interactively\n",
                "\n",
                "Use the `edit_query_time` function to set/change the time range used by queries.\n",
                "\n",
                "With no parameters it defaults to a period of \\[*UtcNow - 1 day*\\] to \\[*UtcNow*\\].\n",
                "\n",
                "Or you can change the timespan to use with the TimeSpan class.\n",
                "Changes that you make to the time range take effect immediately."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 21,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "Help on method edit_query_time in module msticpy.init.pivot:\n",
                        "\n",
                        "edit_query_time(timespan: Optional[msticpy.common.timespan.TimeSpan] = None) method of msticpy.init.pivot.Pivot instance\n",
                        "    Display a QueryTime widget to get the timespan.\n",
                        "    \n",
                        "    Parameters\n",
                        "    ----------\n",
                        "    timespan : Optional[TimeSpan], optional\n",
                        "        Pre-populate the timespan shown by the QueryTime editor,\n",
                        "        by default None\n",
                        "\n"
                    ]
                }
            ],
            "source": [
                "help(mp.pivot.edit_query_time)"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 23,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "application/vnd.jupyter.widget-view+json": {
                            "model_id": "25fe2dc79c034eb7b7e10ffcff3d5e2a",
                            "version_major": 2,
                            "version_minor": 0
                        },
                        "text/plain": [
                            "VBox(children=(HTML(value='<h4>Set time range for pivot functions.</h4>'), HBox(children=(DatePicker(value=dat…"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "mp.pivot.edit_query_time()"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Setting the timespan programmatically\n",
                "You can also just set the timespan directly on the pivot object"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 23,
            "metadata": {},
            "outputs": [],
            "source": [
                "from msticpy.common.timespan import TimeSpan\n",
                "ts = TimeSpan(start=\"2020-10-01\", period=\"1d\")\n",
                "mp.pivot.timespan = ts"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### What queries do we have?"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 31,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "sec_alerts function\n",
                        "VMComputer_vmcomputer function\n",
                        "sent_bookmarks function\n",
                        "az_nsg_net_flows_depr function\n",
                        "az_nsg_interface function\n",
                        "heartbeat function\n",
                        "az_nsg_net_flows function\n",
                        "heartbeat_for_host_depr function\n",
                        "auditd_auditd_all function\n",
                        "syslog_sudo_activity function\n",
                        "syslog_cron_activity function\n",
                        "syslog_user_group_activity function\n",
                        "syslog_all_syslog function\n",
                        "syslog_squid_activity function\n",
                        "syslog_user_logon function\n",
                        "syslog_logons function\n",
                        "syslog_logon_failures function\n",
                        "wevt_all_events function\n",
                        "wevt_events_by_id function\n",
                        "wevt_list_other_events function\n",
                        "wevt_logon_session function\n",
                        "wevt_logons function\n",
                        "wevt_logon_failures function\n",
                        "wevt_logon_attempts function\n",
                        "wevt_processes function\n",
                        "wevt_get_process_tree function\n",
                        "wevt_parent_process function\n",
                        "wevt_process_session function\n"
                    ]
                }
            ],
            "source": [
                "Host.MSSentinel()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 25,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>TenantId</th>\n",
                            "      <th>SourceSystem</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>MG</th>\n",
                            "      <th>ManagementGroupName</th>\n",
                            "      <th>SourceComputerId</th>\n",
                            "      <th>ComputerIP</th>\n",
                            "      <th>Computer</th>\n",
                            "      <th>Category</th>\n",
                            "      <th>OSType</th>\n",
                            "      <th>OSName</th>\n",
                            "      <th>OSMajorVersion</th>\n",
                            "      <th>OSMinorVersion</th>\n",
                            "      <th>Version</th>\n",
                            "      <th>SCAgentChannel</th>\n",
                            "      <th>IsGatewayInstalled</th>\n",
                            "      <th>RemoteIPLongitude</th>\n",
                            "      <th>RemoteIPLatitude</th>\n",
                            "      <th>RemoteIPCountry</th>\n",
                            "      <th>SubscriptionId</th>\n",
                            "      <th>ResourceGroup</th>\n",
                            "      <th>ResourceProvider</th>\n",
                            "      <th>Resource</th>\n",
                            "      <th>ResourceId</th>\n",
                            "      <th>ResourceType</th>\n",
                            "      <th>ComputerEnvironment</th>\n",
                            "      <th>Solutions</th>\n",
                            "      <th>VMUUID</th>\n",
                            "      <th>ComputerPrivateIPs</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>_ResourceId</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "Empty DataFrame\n",
                            "Columns: [TenantId, SourceSystem, TimeGenerated, MG, ManagementGroupName, SourceComputerId, ComputerIP, Computer, Category, OSType, OSName, OSMajorVersion, OSMinorVersion, Version, SCAgentChannel, IsGatewayInstalled, RemoteIPLongitude, RemoteIPLatitude, RemoteIPCountry, SubscriptionId, ResourceGroup, ResourceProvider, Resource, ResourceId, ResourceType, ComputerEnvironment, Solutions, VMUUID, ComputerPrivateIPs, Type, _ResourceId]\n",
                            "Index: []"
                        ]
                    },
                    "execution_count": 25,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "host = Host(HostName=\"VictimPc\")\n",
                "Host.MSSentinel.heartbeat(host)"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 26,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>TenantId</th>\n",
                            "      <th>Account</th>\n",
                            "      <th>EventID</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>SourceComputerId</th>\n",
                            "      <th>Computer</th>\n",
                            "      <th>SubjectUserName</th>\n",
                            "      <th>SubjectDomainName</th>\n",
                            "      <th>SubjectUserSid</th>\n",
                            "      <th>TargetUserName</th>\n",
                            "      <th>TargetDomainName</th>\n",
                            "      <th>TargetUserSid</th>\n",
                            "      <th>TargetLogonId</th>\n",
                            "      <th>LogonProcessName</th>\n",
                            "      <th>LogonType</th>\n",
                            "      <th>LogonTypeName</th>\n",
                            "      <th>AuthenticationPackageName</th>\n",
                            "      <th>Status</th>\n",
                            "      <th>IpAddress</th>\n",
                            "      <th>WorkstationName</th>\n",
                            "      <th>TimeCreatedUtc</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "Empty DataFrame\n",
                            "Columns: [TenantId, Account, EventID, TimeGenerated, SourceComputerId, Computer, SubjectUserName, SubjectDomainName, SubjectUserSid, TargetUserName, TargetDomainName, TargetUserSid, TargetLogonId, LogonProcessName, LogonType, LogonTypeName, AuthenticationPackageName, Status, IpAddress, WorkstationName, TimeCreatedUtc]\n",
                            "Index: []"
                        ]
                    },
                    "execution_count": 26,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Host.MSSentinel.wevt_logons(host_name=\"VictimPc\").head()"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Adding additional parameters\n",
                "\n",
                "The example below shows using the host entity as an initial parameter\n",
                "(Pivot is using the attribute mapping assign the `host_name` function parameter the value of `host.fqdn`).\n",
                "\n",
                "The second parameter is a list of event IDs specified explicitly."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 27,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "\u001b[1;31mSignature:\u001b[0m \u001b[0mHost\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mMSSentinel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwevt_logons\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mpandas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
                        "\u001b[1;31mDocstring:\u001b[0m\n",
                        "Retrieves the logon events on the host\n",
                        "\n",
                        "Parameters\n",
                        "----------\n",
                        "add_query_items: str (optional)\n",
                        "    Additional query clauses\n",
                        "end: datetime\n",
                        "    Query end time\n",
                        "event_filter: str (optional)\n",
                        "    Event subset\n",
                        "    (default value is: | where EventID == 4624)\n",
                        "host_name: str\n",
                        "    Name of host\n",
                        "query_project: str (optional)\n",
                        "    Column project statement\n",
                        "    (default value is:  | project TenantId, Account, EventID, TimeGenerat...)\n",
                        "start: datetime\n",
                        "    Query start time\n",
                        "subscription_filter: str (optional)\n",
                        "    Optional subscription/tenant filter expression\n",
                        "    (default value is: true)\n",
                        "table: str (optional)\n",
                        "    Table name\n",
                        "    (default value is: SecurityEvent)\n",
                        "\u001b[1;31mFile:\u001b[0m      f:\\anaconda\\envs\\msticpy\\lib\\functools.py\n",
                        "\u001b[1;31mType:\u001b[0m      function\n"
                    ]
                }
            ],
            "source": [
                "Host.MSSentinel.wevt_logons?"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 28,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th></th>\n",
                            "      <th>Computer</th>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>EventID</th>\n",
                            "      <th>Activity</th>\n",
                            "      <th></th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "Empty DataFrame\n",
                            "Columns: [Computer]\n",
                            "Index: []"
                        ]
                    },
                    "execution_count": 28,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "(\n",
                "    Host.MSSentinel.wevt_events_by_id(    # Pivot query returns DataFrame\n",
                "        host, event_list=[4624, 4625, 4672]\n",
                "    )\n",
                "    [[\"Computer\", \"EventID\", \"Activity\"]] # we could have save the output to a dataframe\n",
                "    .groupby([\"EventID\", \"Activity\"])     # variable but we can also use pandas\n",
                "    .count()                              # functions/syntax directly on the output\n",
                ")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Using iterables as parameters to data queries\n",
                "\n",
                "Some data queries accept \"list\" items as parameters (e.g. many of the IP queries accept a\n",
                "list of IP addresses). These work as expected, with a single query calling sending the whole list\n",
                "as a single parameter."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 36,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "\u001b[1;31mSignature:\u001b[0m \u001b[0mIpAddress\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mMSSentinel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0maad_signins\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mpandas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
                        "\u001b[1;31mDocstring:\u001b[0m\n",
                        "Lists Azure AD Signins for an IP Address\n",
                        "\n",
                        "Parameters\n",
                        "----------\n",
                        "add_query_items: str (optional)\n",
                        "    Additional query clauses\n",
                        "end: datetime\n",
                        "    Query end time\n",
                        "ip_address_list: list\n",
                        "    The IP Address or list of Addresses\n",
                        "start: datetime\n",
                        "    Query start time\n",
                        "table: str (optional)\n",
                        "    Table name\n",
                        "    (default value is: SigninLogs)\n",
                        "\u001b[1;31mFile:\u001b[0m      f:\\anaconda\\envs\\msticpy\\lib\\functools.py\n",
                        "\u001b[1;31mType:\u001b[0m      function\n"
                    ]
                }
            ],
            "source": [
                "ip_list = [\n",
                "    \"203.23.68.64\",\n",
                "    \"67.10.68.45\",\n",
                "    \"182.69.173.164\",\n",
                "    \"79.176.167.161\",\n",
                "    \"167.220.197.230\",\n",
                "]\n",
                "\n",
                "IpAddress.MSSentinel.aad_signins?"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 37,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<!DOCTYPE html>\n",
                            "            <html><body>\n",
                            "            <div style=''>\n",
                            "            <b>E2JMR3WCG</b>&nbsp;<a href='http://127.0.0.1:29841/webbrowser?url=http%3A//127.0.0.1%3A29841/files/.kqlmagic/temp_files/822246zXwYZm4GxSg/popup_devicelogin.html%3Fkernelid%3D822246zXwYZm4GxSg&kernelid=822246zXwYZm4GxSg' style='padding: 2px 6px 2px 6px; color: #333333; background-color: #EEEEEE; border-top: 1px solid #CCCCCC; border-right: 1px solid #333333; border-bottom: 1px solid #333333; border-left: 1px solid #CCCCCC' target='popup_verification_url'>Copy code to clipboard and authenticate</a>\n",
                            "            </div>\n",
                            "            </body></html>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<!DOCTYPE html>\n",
                            "                            <html><body><script>\n",
                            "\n",
                            "                                // close authentication window\n",
                            "                                if (kql_MagicUserCodeAuthWindow && kql_MagicUserCodeAuthWindow.opener != null && !kql_MagicUserCodeAuthWindow.closed) {\n",
                            "                                    kql_MagicUserCodeAuthWindow.close()\n",
                            "                                }\n",
                            "                                // TODO: make sure, you clear the right cell. BTW, not sure it is a must to do any clearing\n",
                            "\n",
                            "                                // clear output cell\n",
                            "                                Jupyter.notebook.clear_output(Jupyter.notebook.get_selected_index())\n",
                            "\n",
                            "                                // TODO: if in run all mode, move to last cell, otherwise move to next cell\n",
                            "                                // move to next cell\n",
                            "\n",
                            "                            </script></body></html>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/plain": [
                            "pandas.core.frame.DataFrame"
                        ]
                    },
                    "execution_count": 37,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "type(IpAddress.MSSentinel.aad_signins(ip_address_list=ip_list).head(5))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Using iterable values where the query function was designed to only accept single values\n",
                "\n",
                "In this case the pivot function will iterate through the values of the\n",
                "iterable, making a separate query for each and then joining the results.\n",
                "\n",
                "We can see that this function only accepts a single value for \"account_name\"."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 32,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "\u001b[1;31mSignature:\u001b[0m \u001b[0mAccount\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mMSSentinel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0maad_signins\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mpandas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
                        "\u001b[1;31mDocstring:\u001b[0m\n",
                        "Lists Azure AD Signins for Account\n",
                        "\n",
                        "Parameters\n",
                        "----------\n",
                        "account_id: str (optional)\n",
                        "    Azure user ID to find\n",
                        "    (default value is: !!DEFAULT!!)\n",
                        "account_name: str (optional)\n",
                        "    The account name to find\n",
                        "    (default value is: !!DEFAULT!!)\n",
                        "add_query_items: str (optional)\n",
                        "    Additional query clauses\n",
                        "end: datetime\n",
                        "    Query end time\n",
                        "start: datetime\n",
                        "    Query start time\n",
                        "table: str (optional)\n",
                        "    Table name\n",
                        "    (default value is: SigninLogs)\n",
                        "\u001b[1;31mFile:\u001b[0m      f:\\anaconda\\envs\\msticpy\\lib\\functools.py\n",
                        "\u001b[1;31mType:\u001b[0m      function\n"
                    ]
                }
            ],
            "source": [
                "Account.MSSentinel.aad_signins?"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 33,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>TenantId</th>\n",
                            "      <th>SourceSystem</th>\n",
                            "      <th>TimeGenerated</th>\n",
                            "      <th>ResourceId</th>\n",
                            "      <th>OperationName</th>\n",
                            "      <th>OperationVersion</th>\n",
                            "      <th>Category</th>\n",
                            "      <th>ResultType</th>\n",
                            "      <th>ResultSignature</th>\n",
                            "      <th>ResultDescription</th>\n",
                            "      <th>DurationMs</th>\n",
                            "      <th>CorrelationId</th>\n",
                            "      <th>Resource</th>\n",
                            "      <th>ResourceGroup</th>\n",
                            "      <th>ResourceProvider</th>\n",
                            "      <th>Identity</th>\n",
                            "      <th>Level</th>\n",
                            "      <th>Location</th>\n",
                            "      <th>AlternateSignInName</th>\n",
                            "      <th>AppDisplayName</th>\n",
                            "      <th>AppId</th>\n",
                            "      <th>AuthenticationContextClassReferences</th>\n",
                            "      <th>AuthenticationDetails</th>\n",
                            "      <th>AuthenticationMethodsUsed</th>\n",
                            "      <th>AuthenticationProcessingDetails</th>\n",
                            "      <th>...</th>\n",
                            "      <th>RiskState</th>\n",
                            "      <th>ResourceDisplayName</th>\n",
                            "      <th>ResourceIdentity</th>\n",
                            "      <th>ResourceServicePrincipalId</th>\n",
                            "      <th>ServicePrincipalId</th>\n",
                            "      <th>ServicePrincipalName</th>\n",
                            "      <th>Status</th>\n",
                            "      <th>TokenIssuerName</th>\n",
                            "      <th>TokenIssuerType</th>\n",
                            "      <th>UserAgent</th>\n",
                            "      <th>UserDisplayName</th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>UserPrincipalName</th>\n",
                            "      <th>AADTenantId</th>\n",
                            "      <th>UserType</th>\n",
                            "      <th>FlaggedForReview</th>\n",
                            "      <th>IPAddressFromResourceProvider</th>\n",
                            "      <th>SignInIdentifier</th>\n",
                            "      <th>SignInIdentifierType</th>\n",
                            "      <th>ResourceTenantId</th>\n",
                            "      <th>HomeTenantId</th>\n",
                            "      <th>UniqueTokenIdentifier</th>\n",
                            "      <th>SessionLifetimePolicies</th>\n",
                            "      <th>AutonomousSystemNumber</th>\n",
                            "      <th>Type</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "<p>0 rows × 71 columns</p>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "Empty DataFrame\n",
                            "Columns: [TenantId, SourceSystem, TimeGenerated, ResourceId, OperationName, OperationVersion, Category, ResultType, ResultSignature, ResultDescription, DurationMs, CorrelationId, Resource, ResourceGroup, ResourceProvider, Identity, Level, Location, AlternateSignInName, AppDisplayName, AppId, AuthenticationContextClassReferences, AuthenticationDetails, AuthenticationMethodsUsed, AuthenticationProcessingDetails, AuthenticationRequirement, AuthenticationRequirementPolicies, ClientAppUsed, ConditionalAccessPolicies, ConditionalAccessStatus, CreatedDateTime, DeviceDetail, IsInteractive, Id, IPAddress, IsRisky, LocationDetails, MfaDetail, NetworkLocationDetails, OriginalRequestId, ProcessingTimeInMilliseconds, RiskDetail, RiskEventTypes, RiskEventTypes_V2, RiskLevelAggregated, RiskLevelDuringSignIn, RiskState, ResourceDisplayName, ResourceIdentity, ResourceServicePrincipalId, ServicePrincipalId, ServicePrincipalName, Status, TokenIssuerName, TokenIssuerType, UserAgent, UserDisplayName, UserId, UserPrincipalName, AADTenantId, UserType, FlaggedForReview, IPAddressFromResourceProvider, SignInIdentifier, SignInIdentifierType, ResourceTenantId, HomeTenantId, UniqueTokenIdentifier, SessionLifetimePolicies, AutonomousSystemNumber, Type]\n",
                            "Index: []\n",
                            "\n",
                            "[0 rows x 71 columns]"
                        ]
                    },
                    "execution_count": 33,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "accounts = [\n",
                "    \"ofshezaf\",\n",
                "    \"moshabi\",\n",
                "]\n",
                "Account.MSSentinel.aad_signins(account_name=accounts)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Combining multiple iterables and single-valued parameters\n",
                "\n",
                "The same rules as outline earlier for multiple parameters of different types apply to data queries"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 37,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserPrincipalName</th>\n",
                            "      <th>Identity</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "Empty DataFrame\n",
                            "Columns: [UserPrincipalName, Identity]\n",
                            "Index: []"
                        ]
                    },
                    "execution_count": 37,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "project = \"| project UserPrincipalName, Identity\"\n",
                "Account.MSSentinel.aad_signins(account_name=accounts, add_query_items=project)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Using DataFrames as input\n",
                "\n",
                "This is similar to using dataframes for other pivot functions.\n",
                "\n",
                "We must use the `data` parameter to specify the input dataframe.\n",
                "You supply the column name from your input dataframe as the value of\n",
                "the parameters expected by the function."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 35,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>User</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>ofshezaf</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>moshabi</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "       User\n",
                            "0  ofshezaf\n",
                            "1   moshabi"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                }
            ],
            "source": [
                "account_df = pd.DataFrame(accounts, columns=[\"User\"])\n",
                "display(account_df)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Now we have our dataframe:\n",
                "\n",
                "- we specify `account_df` as the value of the `data` parameter.\n",
                "- in our source (input) dataframe, the column that we want to use as the input value for each query is `User`\n",
                "- we specify that column name as the value of the function parameter\n",
                "\n",
                "On each iteration, the column value from a subsequent row will be extracted and \n",
                "given as the parameter value for the function parameter.\n",
                "\n",
                "> Note:<br> \n",
                "> If the function parameter type is a \"list\" type - i.e. it expects a list of values<br>\n",
                "> the parameter value will be sent as a list and only a single query is executed.<br>\n",
                "> If the query function has multiple \"list\" type parameters, these will be<br>\n",
                "> populated in the same way.\n",
                "\n",
                "> Note2:<br>\n",
                "> If you have multiple parameters fed by multiple input columns AND one or more<br>\n",
                "> of the function parameters *is not* a list type, the the query will be broken<br>\n",
                "> into queries for each row. Each sub-query getting its values from a single row<br>\n",
                "> of the input dataframe."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 38,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserPrincipalName</th>\n",
                            "      <th>Identity</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "Empty DataFrame\n",
                            "Columns: [UserPrincipalName, Identity]\n",
                            "Index: []"
                        ]
                    },
                    "execution_count": 38,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Account.MSSentinel.aad_signins(data=account_df, account_name=\"User\", add_query_items=project)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Threat Intelligence Lookups\n",
                "\n",
                "These work in the same way as the functions described earlier. However,\n",
                "there are a few peculiarities of the Threat Intel functions:\n",
                "\n",
                "### IPV4 and IPV6\n",
                "Some providers treat these interchangably and use the same endpoint for both.\n",
                "Other providers do not explicitly support IPV6 (e.g. the Tor exit nodes provider).\n",
                "Still others (notably OTX) use different endpoints for IPv4 and IPv6.\n",
                "\n",
                "If you are querying IPv4 you can use either the `lookup_ip` function or one\n",
                "of the `lookup_ipv4` functions. In most cases, you can also use these functions\n",
                "for a mixture of IPv4 and v6 addresses. However, in cases where a provider\n",
                "does not support IPv6 or uses a different endpoint for IPv6 queries you\n",
                "will get no responses.\n",
                "\n",
                "### Entity mapping to IoC Types\n",
                "This table shows the mapping between and entity type\n",
                "and IoC Types:\n",
                "\n",
                "| Entity     |  IoCType           |\n",
                "| :--------- | :----------------- |\n",
                "| IpAddress  | ipv4, ipv6         |\n",
                "| Dns        | domain             |\n",
                "| File       | filehash (incl     |\n",
                "|            | md5, sha1, sha256) |\n",
                "| Url        | url                |\n",
                "\n",
                "<br>\n",
                "\n",
                "> Note: Where you are using a File entity as a parameter, there is a complication.<br>\n",
                "> A file entity can have multiple hash values (md5, sha1, sha256 and even sha256 authenticode).<br>\n",
                "> The `file_hash` attibute of File is used as the default parameter.<br>\n",
                "> In cases where a file has multiple hashes the highest priority hash (in order<br>\n",
                "> sha256, sha1, md5, sha256ac) is returned.<br>\n",
                "> If you are not using file entities as parameters (and specifying the input values<br>\n",
                "> explicitly or via a Dataframe or iterable) you can ignore this."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 39,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "lookup_ip function\n",
                        "lookup_ipv4 function\n",
                        "lookup_ipv6 function\n"
                    ]
                }
            ],
            "source": [
                "IpAddress.ti()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 39,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>Ioc</th>\n",
                            "      <th>IocType</th>\n",
                            "      <th>SafeIoc</th>\n",
                            "      <th>QuerySubtype</th>\n",
                            "      <th>Provider</th>\n",
                            "      <th>Result</th>\n",
                            "      <th>Severity</th>\n",
                            "      <th>Details</th>\n",
                            "      <th>RawResult</th>\n",
                            "      <th>Reference</th>\n",
                            "      <th>Status</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>dns</td>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>None</td>\n",
                            "      <td>OTX</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'pulse_count': 36, 'names': ['Vertek - Jaff Ransomware', 'Jaff - Malware Domain Feed V2', 'Jaff...</td>\n",
                            "      <td>{'sections': ['general', 'geo', 'url_list', 'passive_dns', 'malware', 'whois', 'http_scans'], 'w...</td>\n",
                            "      <td>https://otx.alienvault.com/api/v1/indicators/domain/fkksjobnn43.org/general</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>dns</td>\n",
                            "      <td></td>\n",
                            "      <td>None</td>\n",
                            "      <td>OPR</td>\n",
                            "      <td>True</td>\n",
                            "      <td>warning</td>\n",
                            "      <td>{'rank': None, 'error': 'Domain not found'}</td>\n",
                            "      <td>{'status_code': 404, 'error': 'Domain not found', 'page_rank_integer': 0, 'page_rank_decimal': 0...</td>\n",
                            "      <td>https://openpagerank.com/api/v1.0/getPageRank?domains[0]=fkksjobnn43.org</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>dns</td>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>None</td>\n",
                            "      <td>RiskIQ</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'summary': {'resolutions': 7, 'certificates': 0, 'malware_hashes': 79, 'projects': 0, 'articles...</td>\n",
                            "      <td>{'summary': {'resolutions': 7, 'certificates': 0, 'malware_hashes': 79, 'projects': 0, 'articles...</td>\n",
                            "      <td>https://community.riskiq.com</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>dns</td>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>information</td>\n",
                            "      <td>{'verbose_msg': 'Domain found in dataset', 'response_code': 1, 'positives': 0, 'detected_urls': ...</td>\n",
                            "      <td>{'Sophos category': 'command and control', 'undetected_downloaded_samples': [], 'whois_timestamp...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/domain/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>dns</td>\n",
                            "      <td>fkksjobnn43.org</td>\n",
                            "      <td>None</td>\n",
                            "      <td>XForce</td>\n",
                            "      <td>False</td>\n",
                            "      <td>information</td>\n",
                            "      <td>Authorization failed. Check account and key details.</td>\n",
                            "      <td>&lt;Response [401 Unauthorized]&gt;</td>\n",
                            "      <td>https://api.xforce.ibmcloud.com/url/fkksjobnn43.org</td>\n",
                            "      <td>401</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "               Ioc IocType          SafeIoc QuerySubtype    Provider  Result  \\\n",
                            "0  fkksjobnn43.org     dns  fkksjobnn43.org         None         OTX    True   \n",
                            "0  fkksjobnn43.org     dns                          None         OPR    True   \n",
                            "0  fkksjobnn43.org     dns  fkksjobnn43.org         None      RiskIQ    True   \n",
                            "0  fkksjobnn43.org     dns  fkksjobnn43.org         None  VirusTotal    True   \n",
                            "0  fkksjobnn43.org     dns  fkksjobnn43.org         None      XForce   False   \n",
                            "\n",
                            "      Severity  \\\n",
                            "0         high   \n",
                            "0      warning   \n",
                            "0         high   \n",
                            "0  information   \n",
                            "0  information   \n",
                            "\n",
                            "                                                                                               Details  \\\n",
                            "0  {'pulse_count': 36, 'names': ['Vertek - Jaff Ransomware', 'Jaff - Malware Domain Feed V2', 'Jaff...   \n",
                            "0                                                          {'rank': None, 'error': 'Domain not found'}   \n",
                            "0  {'summary': {'resolutions': 7, 'certificates': 0, 'malware_hashes': 79, 'projects': 0, 'articles...   \n",
                            "0  {'verbose_msg': 'Domain found in dataset', 'response_code': 1, 'positives': 0, 'detected_urls': ...   \n",
                            "0                                                 Authorization failed. Check account and key details.   \n",
                            "\n",
                            "                                                                                             RawResult  \\\n",
                            "0  {'sections': ['general', 'geo', 'url_list', 'passive_dns', 'malware', 'whois', 'http_scans'], 'w...   \n",
                            "0  {'status_code': 404, 'error': 'Domain not found', 'page_rank_integer': 0, 'page_rank_decimal': 0...   \n",
                            "0  {'summary': {'resolutions': 7, 'certificates': 0, 'malware_hashes': 79, 'projects': 0, 'articles...   \n",
                            "0  {'Sophos category': 'command and control', 'undetected_downloaded_samples': [], 'whois_timestamp...   \n",
                            "0                                                                        <Response [401 Unauthorized]>   \n",
                            "\n",
                            "                                                                     Reference  \\\n",
                            "0  https://otx.alienvault.com/api/v1/indicators/domain/fkksjobnn43.org/general   \n",
                            "0     https://openpagerank.com/api/v1.0/getPageRank?domains[0]=fkksjobnn43.org   \n",
                            "0                                                 https://community.riskiq.com   \n",
                            "0                            https://www.virustotal.com/vtapi/v2/domain/report   \n",
                            "0                          https://api.xforce.ibmcloud.com/url/fkksjobnn43.org   \n",
                            "\n",
                            "   Status  \n",
                            "0       0  \n",
                            "0       0  \n",
                            "0       0  \n",
                            "0       0  \n",
                            "0     401  "
                        ]
                    },
                    "execution_count": 39,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "Dns.ti.lookup_dns(value=\"fkksjobnn43.org\")"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 40,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>Ioc</th>\n",
                            "      <th>IocType</th>\n",
                            "      <th>SafeIoc</th>\n",
                            "      <th>QuerySubtype</th>\n",
                            "      <th>Provider</th>\n",
                            "      <th>Result</th>\n",
                            "      <th>Severity</th>\n",
                            "      <th>Details</th>\n",
                            "      <th>RawResult</th>\n",
                            "      <th>Reference</th>\n",
                            "      <th>Status</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd</td>\n",
                            "      <td>sha256_hash</td>\n",
                            "      <td>02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 51, 'res...</td>\n",
                            "      <td>{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware2'...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/file/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf</td>\n",
                            "      <td>sha256_hash</td>\n",
                            "      <td>06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 55, 'res...</td>\n",
                            "      <td>{'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/file/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff</td>\n",
                            "      <td>sha256_hash</td>\n",
                            "      <td>06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 53, 'res...</td>\n",
                            "      <td>{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware1'...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/file/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                                                                Ioc  \\\n",
                            "0  02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd   \n",
                            "1  06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf   \n",
                            "2  06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff   \n",
                            "\n",
                            "       IocType  \\\n",
                            "0  sha256_hash   \n",
                            "1  sha256_hash   \n",
                            "2  sha256_hash   \n",
                            "\n",
                            "                                                            SafeIoc  \\\n",
                            "0  02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd   \n",
                            "1  06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf   \n",
                            "2  06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff   \n",
                            "\n",
                            "  QuerySubtype    Provider  Result Severity  \\\n",
                            "0         None  VirusTotal    True     high   \n",
                            "1         None  VirusTotal    True     high   \n",
                            "2         None  VirusTotal    True     high   \n",
                            "\n",
                            "                                                                                               Details  \\\n",
                            "0  {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 51, 'res...   \n",
                            "1  {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 55, 'res...   \n",
                            "2  {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 53, 'res...   \n",
                            "\n",
                            "                                                                                             RawResult  \\\n",
                            "0  {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware2'...   \n",
                            "1  {'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201...   \n",
                            "2  {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware1'...   \n",
                            "\n",
                            "                                         Reference  Status  \n",
                            "0  https://www.virustotal.com/vtapi/v2/file/report       0  \n",
                            "1  https://www.virustotal.com/vtapi/v2/file/report       0  \n",
                            "2  https://www.virustotal.com/vtapi/v2/file/report       0  "
                        ]
                    },
                    "execution_count": 40,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "hashes = [\n",
                "    \"02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd\",\n",
                "    \"06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf\",\n",
                "    \"06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff\",\n",
                "]\n",
                "\n",
                "File.ti.lookup_file_hash_VirusTotal(hashes)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Lookup from a DataFrame\n",
                "\n",
                "To specify the source column you can use either \"column\" or \"obs_column\""
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 41,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>hash</th>\n",
                            "      <th>ref</th>\n",
                            "      <th>desc</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd</td>\n",
                            "      <td>item_0</td>\n",
                            "      <td>stuff</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf</td>\n",
                            "      <td>item_1</td>\n",
                            "      <td>stuff</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff</td>\n",
                            "      <td>item_2</td>\n",
                            "      <td>stuff</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                                                               hash     ref  \\\n",
                            "0  02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd  item_0   \n",
                            "1  06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf  item_1   \n",
                            "2  06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff  item_2   \n",
                            "\n",
                            "    desc  \n",
                            "0  stuff  \n",
                            "1  stuff  \n",
                            "2  stuff  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>Ioc</th>\n",
                            "      <th>IocType</th>\n",
                            "      <th>SafeIoc</th>\n",
                            "      <th>QuerySubtype</th>\n",
                            "      <th>Provider</th>\n",
                            "      <th>Result</th>\n",
                            "      <th>Severity</th>\n",
                            "      <th>Details</th>\n",
                            "      <th>RawResult</th>\n",
                            "      <th>Reference</th>\n",
                            "      <th>Status</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd</td>\n",
                            "      <td>sha256_hash</td>\n",
                            "      <td>02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 51, 'res...</td>\n",
                            "      <td>{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware2'...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/file/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf</td>\n",
                            "      <td>sha256_hash</td>\n",
                            "      <td>06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 55, 'res...</td>\n",
                            "      <td>{'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/file/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff</td>\n",
                            "      <td>sha256_hash</td>\n",
                            "      <td>06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff</td>\n",
                            "      <td>None</td>\n",
                            "      <td>VirusTotal</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 53, 'res...</td>\n",
                            "      <td>{'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware1'...</td>\n",
                            "      <td>https://www.virustotal.com/vtapi/v2/file/report</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "                                                                Ioc  \\\n",
                            "0  02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd   \n",
                            "1  06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf   \n",
                            "2  06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff   \n",
                            "\n",
                            "       IocType  \\\n",
                            "0  sha256_hash   \n",
                            "1  sha256_hash   \n",
                            "2  sha256_hash   \n",
                            "\n",
                            "                                                            SafeIoc  \\\n",
                            "0  02a7977d1faf7bfc93a4b678a049c9495ea663e7065aa5a6caf0f69c5ff25dbd   \n",
                            "1  06b020a3fd3296bc4c7bf53307fe7b40638e7f445bdd43fac1d04547a429fdaf   \n",
                            "2  06c676bf8f5c6af99172c1cf63a84348628ae3f39df9e523c42447e2045e00ff   \n",
                            "\n",
                            "  QuerySubtype    Provider  Result Severity  \\\n",
                            "0         None  VirusTotal    True     high   \n",
                            "1         None  VirusTotal    True     high   \n",
                            "2         None  VirusTotal    True     high   \n",
                            "\n",
                            "                                                                                               Details  \\\n",
                            "0  {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 51, 'res...   \n",
                            "1  {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 55, 'res...   \n",
                            "2  {'verbose_msg': 'Scan finished, information embedded', 'response_code': 1, 'positives': 53, 'res...   \n",
                            "\n",
                            "                                                                                             RawResult  \\\n",
                            "0  {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware2'...   \n",
                            "1  {'scans': {'Bkav': {'detected': False, 'version': '1.3.0.9899', 'result': None, 'update': '20201...   \n",
                            "2  {'scans': {'Bkav': {'detected': True, 'version': '1.3.0.9899', 'result': 'W32.AIDetect.malware1'...   \n",
                            "\n",
                            "                                         Reference  Status  \n",
                            "0  https://www.virustotal.com/vtapi/v2/file/report       0  \n",
                            "1  https://www.virustotal.com/vtapi/v2/file/report       0  \n",
                            "2  https://www.virustotal.com/vtapi/v2/file/report       0  "
                        ]
                    },
                    "execution_count": 41,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "hashes_df = pd.DataFrame(\n",
                "    [(fh, f\"item_{idx}\", \"stuff\") for idx, fh in enumerate(hashes)],\n",
                "    columns=[\"hash\", \"ref\", \"desc\"],\n",
                ")\n",
                "display(hashes_df)\n",
                "File.ti.lookup_file_hash_VirusTotal(data=hashes_df, column=\"hash\")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Chaining pivot and other functions\n",
                "\n",
                "Because pivot functions can take dataframes as inputs and return them\n",
                "as outputs, you can create chains of pivot functions.\n",
                "You can also add other items to the chain that input or output\n",
                "dataframes.\n",
                "\n",
                "For example, you could build a chain that included the following:\n",
                "- take IP addresses from firewall alerts\n",
                "- lookup the IPs in Threat Intel providers filtering those that have high severity\n",
                "- lookup the any remote logon events sourced at those IPs\n",
                "- display a timeline of the logons\n",
                "\n",
                "To make building these types of pipelines easier we've implemented some\n",
                "pandas helper functions. These are available in the `mp_pivot`\n",
                "property of pandas DataFrames, once Pivot is imported.\n",
                "\n",
                "### mp_pivot.run\n",
                "\n",
                "`run` lets you run a pivot function as a pandas pipeline operation.\n",
                " \n",
                "Let's take an example of a simple pivot function using a dataframe as input\n",
                "```\n",
                "    IpAddress.util.whois(data=my_df, column=\"Ioc\")\n",
                "```\n",
                "\n",
                "We can us mp_pivot.run to do this:\n",
                "```\n",
                " (\n",
                "     my_df\n",
                "     .query(\"UserCount > 1\")\n",
                "     .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\")\n",
                "     .drop_duplicates()\n",
                " )\n",
                "```\n",
                "The pandas extension takes care of the `data=my_df` parameter. We still have\n",
                "to add any other required parameters (like the column specification in this case.\n",
                "When it runs it returns its output as a DataFrame and the next operation\n",
                "(drop_duplicates()) runs on this output.\n",
                "\n",
                "Depending on the scenario you might want to preserve the existing dataframe\n",
                "contents (most of the pivot functions only return the results of their specific\n",
                "operation - e.g. whois returns ASN information for an IP address). You\n",
                "can carry the columns of the input dataframe over to the output from \n",
                "the pivot function by adding a `join` parameter to the mp_pivot.run() call.\n",
                "Use a \"left\" to keep all of the input rows regardless of whether the pivot\n",
                "function returned a result for that row.\n",
                "Use an \"inner\" join to return only rows where the input had a positive result\n",
                "in the pivot function.\n",
                "```\n",
                "    .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\", join=\"inner\")\n",
                "```\n",
                "\n",
                "There are also a couple of convenience functions. These only work in\n",
                "an IPython/Jupyter environment.\n",
                "\n",
                "### mp_pivot.display\n",
                "\n",
                "`mp_pivot.display` will display the intermediate results of the dataframe in the middle\n",
                "of a pipeline. It does not change the data at all, but does give you the \n",
                "chance to display a view of the data partway through processing. This\n",
                "is useful for debugging but its main purpose is to give you a way to\n",
                "show partial results without having to break the pipeline into pieces\n",
                "and create unnecessary throw-away variables that will add bulk to your\n",
                "code and clutter to your memory.\n",
                "\n",
                "`display` supports some options that you can use to modify the displayed\n",
                "output:\n",
                "\n",
                "- title - displays a title above the data\n",
                "- cols - a list of columns to display (others are hidden)\n",
                "- query - you can filter the output using a df.query() string. See https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html?highlight=query#pandas.DataFrame.query\n",
                "  for more details\n",
                "- head - limits the display to the first `head` rows\n",
                "\n",
                "These options do not affect the data being passed through the pipeline -\n",
                "only how the intermediate output is displayed.\n",
                "\n",
                "### mp_pivot.tee\n",
                "`mp_pivot.tee` behaves a little like the Linux \"tee\" command. It allows the\n",
                "data to pass through unchanged but allows you to create a variable that\n",
                "is a snapshot of the data at that point in the pipeline. It takes\n",
                "a parameter `var_name` and assigns the current DataFrame instance\n",
                "to that name. So, when your pipeline has run you can access partial results (again,\n",
                "without having to break up your pipeline to do so).\n",
                "\n",
                "By default, it will not overwrite an existing variable of the same name\n",
                "unless you specify `clobber=True` in the call to `tee`.\n",
                "\n",
                "### mp_pivot.tee_exec\n",
                "behaves similarly to the \"tee\" function above except that it\n",
                "will try to execute the DataFrame accessor function on the input\n",
                "DataFrame. The name of the function (as a string) can be passed named as the value of the\n",
                "`df_func` named parameter, or the first positional.\n",
                "The function **must** be a method of a pandas DataFrame - this includes\n",
                "built-in functions such as `.query`, `.sort_values` or a custom function\n",
                "added as a custom pd accessor function (see \n",
                "[Extending pandas](https://pandas.pydata.org/pandas-docs/stable/development/extending.html?highlight=accessor))\n",
                "\n",
                "`mp_pivot.tee_exec` allows the input\n",
                "data to pass through unchanged but will also send\n",
                "a snapshot of the data at that point in the pipeline to the named function.\n",
                "You can also pass arbitrary other named arguments to the `tee_exec`. These arguments will be passed to the `df_func` function.\n",
                "\n",
                "### Example\n",
                "The example below shows the use of mp_pivot.run and mp_pivot.display.\n",
                "\n",
                "This takes an existing DataFrame - suspcious_ips - and:\n",
                "\n",
                "- displays the top 5 rows of the dataframe\n",
                "- checks for threat intelligence reports on any of the IP addresses\n",
                "- uses pandas `query` to filter only the high severity hits\n",
                "- calls the whois pivot function to obtain ownership information for these IPs\n",
                "  (note that we join the results of the previous step here usine `join='left'`\n",
                "  so our output will be all TI result data plus whois data\n",
                "- calls a pivot data query to check for Azure Active Directory logins that\n",
                "  have an IP address source that matches any of these addresses.\n",
                "  \n",
                "The final step uses another MSTICPy pandas extension to plot the login attempts\n",
                "on a timeline chart."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 42,
            "metadata": {},
            "outputs": [],
            "source": [
                "suspicious_ips = [\n",
                "    \"212.109.217.155\",\n",
                "    \"103.141.68.38\",\n",
                "    \"165.255.70.149\",\n",
                "    \"206.1.228.141\",\n",
                "]\n",
                "suspicious_ips_df = pd.DataFrame(suspicious_ips, columns=[\"IPAddress\"])"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 45,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<h3>Initial IPs 4</h3>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>IPAddress</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>113.190.36.2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>118.163.135.17</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>118.163.135.18</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>118.163.97.19</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>125.34.240.33</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "        IPAddress\n",
                            "0    113.190.36.2\n",
                            "1  118.163.135.17\n",
                            "2  118.163.135.18\n",
                            "3   118.163.97.19\n",
                            "4   125.34.240.33"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<h3>TI High Severity IPs</h3>"
                        ],
                        "text/plain": [
                            "<IPython.core.display.HTML object>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>Ioc</th>\n",
                            "      <th>IocType</th>\n",
                            "      <th>SafeIoc</th>\n",
                            "      <th>QuerySubtype</th>\n",
                            "      <th>Provider</th>\n",
                            "      <th>Result</th>\n",
                            "      <th>Severity</th>\n",
                            "      <th>Details</th>\n",
                            "      <th>RawResult</th>\n",
                            "      <th>Reference</th>\n",
                            "      <th>Status</th>\n",
                            "      <th>nir</th>\n",
                            "      <th>asn_registry</th>\n",
                            "      <th>asn</th>\n",
                            "      <th>asn_cidr</th>\n",
                            "      <th>asn_country_code</th>\n",
                            "      <th>asn_date</th>\n",
                            "      <th>asn_description</th>\n",
                            "      <th>query</th>\n",
                            "      <th>nets</th>\n",
                            "      <th>raw</th>\n",
                            "      <th>referral</th>\n",
                            "      <th>raw_referral</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>113.190.36.2</td>\n",
                            "      <td>ipv4</td>\n",
                            "      <td>113.190.36.2</td>\n",
                            "      <td>None</td>\n",
                            "      <td>OTX</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'pulse_count': 46, 'names': ['Analysis Report (AR21-013A) - Strengthening Security Configuratio...</td>\n",
                            "      <td>{'whois': 'http://whois.domaintools.com/113.190.36.2', 'reputation': 0, 'indicator': '113.190.36...</td>\n",
                            "      <td>https://otx.alienvault.com/api/v1/indicators/IPv4/113.190.36.2/general</td>\n",
                            "      <td>0</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>45899</td>\n",
                            "      <td>113.190.32.0/20</td>\n",
                            "      <td>VN</td>\n",
                            "      <td>2008-11-04</td>\n",
                            "      <td>VNPT-AS-VN VNPT Corp, VN</td>\n",
                            "      <td>113.190.36.2</td>\n",
                            "      <td>[{'cidr': '113.160.0.0/11', 'name': 'VNPT-VN', 'handle': 'PTH13-AP', 'range': '113.160.0.0 - 113...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>118.163.135.17</td>\n",
                            "      <td>ipv4</td>\n",
                            "      <td>118.163.135.17</td>\n",
                            "      <td>None</td>\n",
                            "      <td>OTX</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'pulse_count': 50, 'names': ['IOCs - 20201122247 - ANIA Threat Feeds - IP Segment 0', 'IOCs - 2...</td>\n",
                            "      <td>{'whois': 'http://whois.domaintools.com/118.163.135.17', 'reputation': 0, 'indicator': '118.163....</td>\n",
                            "      <td>https://otx.alienvault.com/api/v1/indicators/IPv4/118.163.135.17/general</td>\n",
                            "      <td>0</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>3462</td>\n",
                            "      <td>118.163.0.0/16</td>\n",
                            "      <td>TW</td>\n",
                            "      <td>2007-10-04</td>\n",
                            "      <td>HINET Data Communication Business Group, TW</td>\n",
                            "      <td>118.163.135.17</td>\n",
                            "      <td>[{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>118.163.135.18</td>\n",
                            "      <td>ipv4</td>\n",
                            "      <td>118.163.135.18</td>\n",
                            "      <td>None</td>\n",
                            "      <td>OTX</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'pulse_count': 50, 'names': ['Analysis Report (AR21-013A) - Strengthening Security Configuratio...</td>\n",
                            "      <td>{'whois': 'http://whois.domaintools.com/118.163.135.18', 'reputation': 0, 'indicator': '118.163....</td>\n",
                            "      <td>https://otx.alienvault.com/api/v1/indicators/IPv4/118.163.135.18/general</td>\n",
                            "      <td>0</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>3462</td>\n",
                            "      <td>118.163.0.0/16</td>\n",
                            "      <td>TW</td>\n",
                            "      <td>2007-10-04</td>\n",
                            "      <td>HINET Data Communication Business Group, TW</td>\n",
                            "      <td>118.163.135.18</td>\n",
                            "      <td>[{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>118.163.97.19</td>\n",
                            "      <td>ipv4</td>\n",
                            "      <td>118.163.97.19</td>\n",
                            "      <td>None</td>\n",
                            "      <td>OTX</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'pulse_count': 50, 'names': ['Analysis Report (AR21-013A) - Strengthening Security Configuratio...</td>\n",
                            "      <td>{'whois': 'http://whois.domaintools.com/118.163.97.19', 'reputation': 0, 'indicator': '118.163.9...</td>\n",
                            "      <td>https://otx.alienvault.com/api/v1/indicators/IPv4/118.163.97.19/general</td>\n",
                            "      <td>0</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>3462</td>\n",
                            "      <td>118.163.0.0/16</td>\n",
                            "      <td>TW</td>\n",
                            "      <td>2007-10-04</td>\n",
                            "      <td>HINET Data Communication Business Group, TW</td>\n",
                            "      <td>118.163.97.19</td>\n",
                            "      <td>[{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>125.34.240.33</td>\n",
                            "      <td>ipv4</td>\n",
                            "      <td>125.34.240.33</td>\n",
                            "      <td>None</td>\n",
                            "      <td>OTX</td>\n",
                            "      <td>True</td>\n",
                            "      <td>high</td>\n",
                            "      <td>{'pulse_count': 50, 'names': ['IOCs - 20223111348 - ANIA Threat Feeds - IP Segment 4', 'IOCs - 2...</td>\n",
                            "      <td>{'whois': 'http://whois.domaintools.com/125.34.240.33', 'reputation': 0, 'indicator': '125.34.24...</td>\n",
                            "      <td>https://otx.alienvault.com/api/v1/indicators/IPv4/125.34.240.33/general</td>\n",
                            "      <td>0</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>4837</td>\n",
                            "      <td>125.34.240.0/24</td>\n",
                            "      <td>CN</td>\n",
                            "      <td>2006-01-09</td>\n",
                            "      <td>CHINA169-BACKBONE CHINA UNICOM China169 Backbone, CN</td>\n",
                            "      <td>125.34.240.33</td>\n",
                            "      <td>[{'cidr': '125.34.0.0/16', 'name': 'UNICOM-BJ', 'handle': 'CH1302-AP', 'range': '125.34.0.0 - 12...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "              Ioc IocType         SafeIoc QuerySubtype Provider  Result  \\\n",
                            "0    113.190.36.2    ipv4    113.190.36.2         None      OTX    True   \n",
                            "1  118.163.135.17    ipv4  118.163.135.17         None      OTX    True   \n",
                            "2  118.163.135.18    ipv4  118.163.135.18         None      OTX    True   \n",
                            "3   118.163.97.19    ipv4   118.163.97.19         None      OTX    True   \n",
                            "4   125.34.240.33    ipv4   125.34.240.33         None      OTX    True   \n",
                            "\n",
                            "  Severity  \\\n",
                            "0     high   \n",
                            "1     high   \n",
                            "2     high   \n",
                            "3     high   \n",
                            "4     high   \n",
                            "\n",
                            "                                                                                               Details  \\\n",
                            "0  {'pulse_count': 46, 'names': ['Analysis Report (AR21-013A) - Strengthening Security Configuratio...   \n",
                            "1  {'pulse_count': 50, 'names': ['IOCs - 20201122247 - ANIA Threat Feeds - IP Segment 0', 'IOCs - 2...   \n",
                            "2  {'pulse_count': 50, 'names': ['Analysis Report (AR21-013A) - Strengthening Security Configuratio...   \n",
                            "3  {'pulse_count': 50, 'names': ['Analysis Report (AR21-013A) - Strengthening Security Configuratio...   \n",
                            "4  {'pulse_count': 50, 'names': ['IOCs - 20223111348 - ANIA Threat Feeds - IP Segment 4', 'IOCs - 2...   \n",
                            "\n",
                            "                                                                                             RawResult  \\\n",
                            "0  {'whois': 'http://whois.domaintools.com/113.190.36.2', 'reputation': 0, 'indicator': '113.190.36...   \n",
                            "1  {'whois': 'http://whois.domaintools.com/118.163.135.17', 'reputation': 0, 'indicator': '118.163....   \n",
                            "2  {'whois': 'http://whois.domaintools.com/118.163.135.18', 'reputation': 0, 'indicator': '118.163....   \n",
                            "3  {'whois': 'http://whois.domaintools.com/118.163.97.19', 'reputation': 0, 'indicator': '118.163.9...   \n",
                            "4  {'whois': 'http://whois.domaintools.com/125.34.240.33', 'reputation': 0, 'indicator': '125.34.24...   \n",
                            "\n",
                            "                                                                  Reference  \\\n",
                            "0    https://otx.alienvault.com/api/v1/indicators/IPv4/113.190.36.2/general   \n",
                            "1  https://otx.alienvault.com/api/v1/indicators/IPv4/118.163.135.17/general   \n",
                            "2  https://otx.alienvault.com/api/v1/indicators/IPv4/118.163.135.18/general   \n",
                            "3   https://otx.alienvault.com/api/v1/indicators/IPv4/118.163.97.19/general   \n",
                            "4   https://otx.alienvault.com/api/v1/indicators/IPv4/125.34.240.33/general   \n",
                            "\n",
                            "   Status   nir asn_registry    asn         asn_cidr asn_country_code  \\\n",
                            "0       0  None        apnic  45899  113.190.32.0/20               VN   \n",
                            "1       0  None        apnic   3462   118.163.0.0/16               TW   \n",
                            "2       0  None        apnic   3462   118.163.0.0/16               TW   \n",
                            "3       0  None        apnic   3462   118.163.0.0/16               TW   \n",
                            "4       0  None        apnic   4837  125.34.240.0/24               CN   \n",
                            "\n",
                            "     asn_date                                       asn_description  \\\n",
                            "0  2008-11-04                              VNPT-AS-VN VNPT Corp, VN   \n",
                            "1  2007-10-04           HINET Data Communication Business Group, TW   \n",
                            "2  2007-10-04           HINET Data Communication Business Group, TW   \n",
                            "3  2007-10-04           HINET Data Communication Business Group, TW   \n",
                            "4  2006-01-09  CHINA169-BACKBONE CHINA UNICOM China169 Backbone, CN   \n",
                            "\n",
                            "            query  \\\n",
                            "0    113.190.36.2   \n",
                            "1  118.163.135.17   \n",
                            "2  118.163.135.18   \n",
                            "3   118.163.97.19   \n",
                            "4   125.34.240.33   \n",
                            "\n",
                            "                                                                                                  nets  \\\n",
                            "0  [{'cidr': '113.160.0.0/11', 'name': 'VNPT-VN', 'handle': 'PTH13-AP', 'range': '113.160.0.0 - 113...   \n",
                            "1  [{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...   \n",
                            "2  [{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...   \n",
                            "3  [{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...   \n",
                            "4  [{'cidr': '125.34.0.0/16', 'name': 'UNICOM-BJ', 'handle': 'CH1302-AP', 'range': '125.34.0.0 - 12...   \n",
                            "\n",
                            "    raw referral raw_referral  \n",
                            "0  None     None         None  \n",
                            "1  None     None         None  \n",
                            "2  None     None         None  \n",
                            "3  None     None         None  \n",
                            "4  None     None         None  "
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "text/html": [
                            "\n",
                            "    <div class=\"bk-root\">\n",
                            "        <a href=\"https://bokeh.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
                            "        <span id=\"1002\">Loading BokehJS ...</span>\n",
                            "    </div>"
                        ]
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "data": {
                        "application/javascript": "\n(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  const force = true;\n\n  if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n    root._bokeh_onload_callbacks = [];\n    root._bokeh_is_loading = undefined;\n  }\n\n  const JS_MIME_TYPE = 'application/javascript';\n  const HTML_MIME_TYPE = 'text/html';\n  const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n  const CLASS_NAME = 'output_bokeh rendered_html';\n\n  /**\n   * Render data to the DOM node\n   */\n  function render(props, node) {\n    const script = document.createElement(\"script\");\n    node.appendChild(script);\n  }\n\n  /**\n   * Handle when an output is cleared or removed\n   */\n  function handleClearOutput(event, handle) {\n    const cell = handle.cell;\n\n    const id = cell.output_area._bokeh_element_id;\n    const server_id = cell.output_area._bokeh_server_id;\n    // Clean up Bokeh references\n    if (id != null && id in Bokeh.index) {\n      Bokeh.index[id].model.document.clear();\n      delete Bokeh.index[id];\n    }\n\n    if (server_id !== undefined) {\n      // Clean up Bokeh references\n      const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n      cell.notebook.kernel.execute(cmd_clean, {\n        iopub: {\n          output: function(msg) {\n            const id = msg.content.text.trim();\n            if (id in Bokeh.index) {\n              Bokeh.index[id].model.document.clear();\n              delete Bokeh.index[id];\n            }\n          }\n        }\n      });\n      // Destroy server and session\n      const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n      cell.notebook.kernel.execute(cmd_destroy);\n    }\n  }\n\n  /**\n   * Handle when a new output is added\n   */\n  function handleAddOutput(event, handle) {\n    const output_area = handle.output_area;\n    const output = handle.output;\n\n    // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n    if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n      return\n    }\n\n    const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n    if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n      toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n      // store reference to embed id on output_area\n      output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n    }\n    if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n      const bk_div = document.createElement(\"div\");\n      bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n      const script_attrs = bk_div.children[0].attributes;\n      for (let i = 0; i < script_attrs.length; i++) {\n        toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n        toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n      }\n      // store reference to server id on output_area\n      output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n    }\n  }\n\n  function register_renderer(events, OutputArea) {\n\n    function append_mime(data, metadata, element) {\n      // create a DOM node to render to\n      const toinsert = this.create_output_subarea(\n        metadata,\n        CLASS_NAME,\n        EXEC_MIME_TYPE\n      );\n      this.keyboard_manager.register_events(toinsert);\n      // Render to node\n      const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n      render(props, toinsert[toinsert.length - 1]);\n      element.append(toinsert);\n      return toinsert\n    }\n\n    /* Handle when an output is cleared or removed */\n    events.on('clear_output.CodeCell', handleClearOutput);\n    events.on('delete.Cell', handleClearOutput);\n\n    /* Handle when a new output is added */\n    events.on('output_added.OutputArea', handleAddOutput);\n\n    /**\n     * Register the mime type and append_mime function with output_area\n     */\n    OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n      /* Is output safe? */\n      safe: true,\n      /* Index of renderer in `output_area.display_order` */\n      index: 0\n    });\n  }\n\n  // register the mime type if in Jupyter Notebook environment and previously unregistered\n  if (root.Jupyter !== undefined) {\n    const events = require('base/js/events');\n    const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n      register_renderer(events, OutputArea);\n    }\n  }\n\n  \n  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  const NB_LOAD_WARNING = {'data': {'text/html':\n     \"<div style='background-color: #fdd'>\\n\"+\n     \"<p>\\n\"+\n     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n     \"</p>\\n\"+\n     \"<ul>\\n\"+\n     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n     \"</ul>\\n\"+\n     \"<code>\\n\"+\n     \"from bokeh.resources import INLINE\\n\"+\n     \"output_notebook(resources=INLINE)\\n\"+\n     \"</code>\\n\"+\n     \"</div>\"}};\n\n  function display_loaded() {\n    const el = document.getElementById(\"1002\");\n    if (el != null) {\n      el.textContent = \"BokehJS is loading...\";\n    }\n    if (root.Bokeh !== undefined) {\n      if (el != null) {\n        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(display_loaded, 100)\n    }\n  }\n\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) {\n        if (callback != null)\n          callback();\n      });\n    } finally {\n      delete root._bokeh_onload_callbacks\n    }\n    console.debug(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(css_urls, js_urls, callback) {\n    if (css_urls == null) css_urls = [];\n    if (js_urls == null) js_urls = [];\n\n    root._bokeh_onload_callbacks.push(callback);\n    if (root._bokeh_is_loading > 0) {\n      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls == null || js_urls.length === 0) {\n      run_callbacks();\n      return null;\n    }\n    console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n    function on_load() {\n      root._bokeh_is_loading--;\n      if (root._bokeh_is_loading === 0) {\n        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n        run_callbacks()\n      }\n    }\n\n    function on_error(url) {\n      console.error(\"failed to load \" + url);\n    }\n\n    for (let i = 0; i < css_urls.length; i++) {\n      const url = css_urls[i];\n      const element = document.createElement(\"link\");\n      element.onload = on_load;\n      element.onerror = on_error.bind(null, url);\n      element.rel = \"stylesheet\";\n      element.type = \"text/css\";\n      element.href = url;\n      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n      document.body.appendChild(element);\n    }\n\n    for (let i = 0; i < js_urls.length; i++) {\n      const url = js_urls[i];\n      const element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error.bind(null, url);\n      element.async = false;\n      element.src = url;\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n  };\n\n  function inject_raw_css(css) {\n    const element = document.createElement(\"style\");\n    element.appendChild(document.createTextNode(css));\n    document.body.appendChild(element);\n  }\n\n  \n  const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js\"];\n  const css_urls = [];\n  \n\n  const inline_js = [\n    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    function(Bokeh) {\n    \n    \n    }\n  ];\n\n  function run_inline_js() {\n    \n    if (root.Bokeh !== undefined || force === true) {\n      \n    for (let i = 0; i < inline_js.length; i++) {\n      inline_js[i].call(root, root.Bokeh);\n    }\n    if (force === true) {\n        display_loaded();\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    } else if (force !== true) {\n      const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n    }\n\n  }\n\n  if (root._bokeh_is_loading === 0) {\n    console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n    run_inline_js();\n  } else {\n    load_libs(css_urls, js_urls, function() {\n      console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n      run_inline_js();\n    });\n  }\n}(window));",
                        "application/vnd.bokehjs_load.v0+json": ""
                    },
                    "metadata": {},
                    "output_type": "display_data"
                },
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "No data to plot.\n"
                    ]
                },
                {
                    "data": {
                        "text/html": [
                            "<div style=\"display: table;\"><div style=\"display: table-row;\"><div style=\"display: table-cell;\"><b title=\"bokeh.plotting.figure.Figure\">Figure</b>(</div><div style=\"display: table-cell;\">id&nbsp;=&nbsp;'1003', <span id=\"1035\" style=\"cursor: pointer;\">&hellip;)</span></div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">above&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">align&nbsp;=&nbsp;'start',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">aspect_ratio&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">aspect_scale&nbsp;=&nbsp;1,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">background&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">background_fill_alpha&nbsp;=&nbsp;1.0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">background_fill_color&nbsp;=&nbsp;'#ffffff',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">below&nbsp;=&nbsp;[LinearAxis(id='1012', ...)],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">border_fill_alpha&nbsp;=&nbsp;1.0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">border_fill_color&nbsp;=&nbsp;'#ffffff',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">center&nbsp;=&nbsp;[Grid(id='1015', ...), Grid(id='1019', ...)],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">css_classes&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">disabled&nbsp;=&nbsp;False,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">extra_x_ranges&nbsp;=&nbsp;{},</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">extra_x_scales&nbsp;=&nbsp;{},</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">extra_y_ranges&nbsp;=&nbsp;{},</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">extra_y_scales&nbsp;=&nbsp;{},</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">frame_height&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">frame_width&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">height&nbsp;=&nbsp;600,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">height_policy&nbsp;=&nbsp;'auto',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">hidpi&nbsp;=&nbsp;True,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">inner_height&nbsp;=&nbsp;0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">inner_width&nbsp;=&nbsp;0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">js_event_callbacks&nbsp;=&nbsp;{},</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">js_property_callbacks&nbsp;=&nbsp;{},</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">left&nbsp;=&nbsp;[LinearAxis(id='1016', ...)],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">lod_factor&nbsp;=&nbsp;10,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">lod_interval&nbsp;=&nbsp;300,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">lod_threshold&nbsp;=&nbsp;2000,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">lod_timeout&nbsp;=&nbsp;500,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">margin&nbsp;=&nbsp;(0, 0, 0, 0),</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">match_aspect&nbsp;=&nbsp;False,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">max_height&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">max_width&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_border&nbsp;=&nbsp;5,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_border_bottom&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_border_left&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_border_right&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_border_top&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_height&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">min_width&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">name&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outer_height&nbsp;=&nbsp;0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outer_width&nbsp;=&nbsp;0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_alpha&nbsp;=&nbsp;1.0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_cap&nbsp;=&nbsp;'butt',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_color&nbsp;=&nbsp;'#e5e5e5',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_dash&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_dash_offset&nbsp;=&nbsp;0,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_join&nbsp;=&nbsp;'bevel',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">outline_line_width&nbsp;=&nbsp;1,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">output_backend&nbsp;=&nbsp;'canvas',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">renderers&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">reset_policy&nbsp;=&nbsp;'standard',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">right&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">sizing_mode&nbsp;=&nbsp;None,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">subscribed_events&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">syncable&nbsp;=&nbsp;True,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">tags&nbsp;=&nbsp;[],</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">title&nbsp;=&nbsp;Title(id='1036', ...),</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">title_location&nbsp;=&nbsp;'above',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">toolbar&nbsp;=&nbsp;Toolbar(id='1027', ...),</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">toolbar_location&nbsp;=&nbsp;'right',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">toolbar_sticky&nbsp;=&nbsp;True,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">visible&nbsp;=&nbsp;True,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">width&nbsp;=&nbsp;600,</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">width_policy&nbsp;=&nbsp;'auto',</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">x_range&nbsp;=&nbsp;DataRange1d(id='1004', ...),</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">x_scale&nbsp;=&nbsp;LinearScale(id='1008', ...),</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">y_range&nbsp;=&nbsp;DataRange1d(id='1006', ...),</div></div><div class=\"1034\" style=\"display: none;\"><div style=\"display: table-cell;\"></div><div style=\"display: table-cell;\">y_scale&nbsp;=&nbsp;LinearScale(id='1010', ...))</div></div></div>\n",
                            "<script>\n",
                            "(function() {\n",
                            "  let expanded = false;\n",
                            "  const ellipsis = document.getElementById(\"1035\");\n",
                            "  ellipsis.addEventListener(\"click\", function() {\n",
                            "    const rows = document.getElementsByClassName(\"1034\");\n",
                            "    for (let i = 0; i < rows.length; i++) {\n",
                            "      const el = rows[i];\n",
                            "      el.style.display = expanded ? \"none\" : \"table-row\";\n",
                            "    }\n",
                            "    ellipsis.innerHTML = expanded ? \"&hellip;)\" : \"&lsaquo;&lsaquo;&lsaquo;\";\n",
                            "    expanded = !expanded;\n",
                            "  });\n",
                            "})();\n",
                            "</script>\n"
                        ],
                        "text/plain": [
                            "Figure(id='1003', ...)"
                        ]
                    },
                    "execution_count": 45,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "(\n",
                "    suspicious_ips_df\n",
                "    .mp_pivot.display(title=f\"Initial IPs {len(suspicious_ips)}\", head=5)\n",
                "    # Lookup IPs at OTX\n",
                "    .mp_pivot.run(IpAddress.ti.lookup_ipv4_OTX, column=\"IPAddress\")\n",
                "    # Filter on high severity\n",
                "    .query(\"Severity == 'high'\")\n",
                "    .mp_pivot.run(IpAddress.util.whois, column=\"Ioc\", join=\"left\")\n",
                "    .mp_pivot.display(title=\"TI High Severity IPs\", head=5)\n",
                "    # Query IPs that have login attempts\n",
                "    .mp_pivot.run(IpAddress.MSSentinel.aad_signins, ip_address_list=\"Ioc\")\n",
                "    # Send the output of this to a plot\n",
                "    .mp_plot.timeline(\n",
                "        title=\"High Severity IPs with Logon attempts\",\n",
                "        source_columns=[\"UserPrincipalName\", \"IPAddress\", \"ResultType\", \"ClientAppUsed\", \"UserAgent\", \"Location\"],\n",
                "        group_by=\"UserPrincipalName\"\n",
                "    )\n",
                ")"
            ]
        },
        {
            "attachments": {
                "0f98df03-f8db-4ddc-a8cd-2535ff315af5.png": {
                    "image/png": "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lZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu6BEdkGF7IIS2QWVmLKLeYSionAHgAwU7igTFqxQIbugRHZBheyCEtkFlZiyi3mEoqJwB4AMFO4oExasUCG7oER2QYXsghLZBZWYsot5hKKicAeADBTuKBMWrFAhu4rh1Acf27tvvT/sYfSM7IIK2TU4Zz/73N5+7YRduDA97KEMDNkFlZiyi3mEoqJwB4AMFO4oExasUCG7Rt+5s+dsx9I9tvIbm+3t104Mezg9IbugQnYNzoN3PG5L//cGe/boC8MeysCQXVCJKbuYRygqCncAyEDhjjJhwQoVsmv0HTv0Q7vsvy+373zlGtuxdI+dO3tu2EPKjeyCCtk1GK/+7E275h/X27/950V23be22ntvfzDsIQ0E2QWVmLKLeYSionAHgAwU7igTFqxQIbtG29uvnbBl/2eDLfy762zNv22zq/5mtT2276lhDys3sgsqZJfemU/P2IZLbrGr/ma1NS+71S7/Hyvt1uV7o9hahuyCSkzZxTxCUVG4A0AGCneUCQtWqJBdo+vk+6fsjjUHrPH1tXbDJbfYlgW7bOHX1tqKf9poLz//+rCHlwvZBRWyS29iz5O26Gtr7Np/3WJbFuyyFf+80RZ+da098/BPhz00ObILKjFlF/MIRUXhDgAZKNxRJixYoUJ2ja4n7/+xLfraOlv5jc22ZcEu27Jgl93wvVut8fV1dtvKe+yDEyeHPcSuyC6okF1av3j2V7bkf22wxX+/biZ/tizYZQu/utauq2+113/+m2EPUYrsgkpM2cU8QlFRuANABgp3lAkLVqiQXaPp1RffsFXf3GwLv7q2rezasmCXrf7mZlv0tbX2/QPPDHuYXZFdUCG7dP7wuw9s+zV32aKvr7PmZTvb8uf6i3dY4+tr7a4N99knJ08Pe6gyZBdUYsou5hGKisIdADJQuKNMWLBChewaPf5WMhu+u2NW4V6krWXILqiQXTrhVjLhLYatZcguqMSUXcwjFBWFOwBkoHBHmbBghQrZNXqeP/YLu+J/rrRrv5Vedm1ZsMs2X3mbfecr19j+rQ8Ne7iZyC6okF0a7771vi37/26wRV+b/a9r/Nvlf73C1v37TcMergzZBZWYsot5hKKicAeADBTuKBMWrFAhu0bP73/znq36xubMwmtNfZstGLvWnn7wJ8MebiayCypkl8bZzz63G6/aZQtqq+3Gq9Lzp3nZrXb5/1xld649OOzhypBdUIkpu5hHKCoKdwDIMOi/4A8ePGhf+tKXBnY8xOVLX/qSHTxY3v+xxfCQXaPpmYd/ao2vr7MV/7xxVtm14bs7bPE/rLc71x20j/748bCHmulLX/qSHThwYNjDQAmRXTovP/+6rfzGJlv09XWphXvj6+ts/cU325tT5S0NyS6ouOyanp4e9lDkKNxRVBTuAJBh0H/BX3rppXbRRUQzNC666CK79NJLhz0MlBDZNZo+OXna7r7hsC3+h/V2/cXt+7gv+to6u/Zft9grL74x7GF2RXZBhezSeuK+Z63x9+ts9Tc3t+VPst3MOvvxoz8b9hClyC6oXPan7KJwB0YXqwsAyPDWW2/Zd7/7Xbv00ksHcvvyl788szjnxq3ft4suusi+/OUvD30c3Mp3I7tG9/bN//OvVv2//6v9+X/4C/vKn/2VfeXP/soq/9d/sT//D//J/r72v4Y+vjw3soub6kZ2aW//Vv93+8vKX9uf/8e/sP/8pb+0r/zZX9l/+n/+X/vz//gX9tf/Zcwu/s7g1tjDuJFd3FS3mLLrrrvuonBHIVG4A0CGQ4cO2UUXXcSNGzdu3Lhx48aNGzdu3LhxG+Dty1/+sp0/f37YtQDQMwp3ABghVy9YYBddRDRD46KLLrKrFywY9jBQQmQXlC666CJbQHZBgOyCEtkFFZddMWwpAxQVqwsAGCH8jx+UKNyhQnZBidIKKmQXlMguqFC4A6OP1QUAjBD+xw9KFO5QIbugRGkFFbILSmQXVCjcgdHH6gIARgj/4wclCneokF1QorSCCtkFJbILKhTuwOhjdQEAI4T/8YMShTtUyC4oUVpBheyCEtkFFQp3YPSxugCAEcL/+EGJwh0qZBeUKK2gQnZBieyCCoU7MPpYXQDACOF//KBE4Q4VsgtKlFZQIbugRHZBhcIdGH2sLgBghPA/flCicIcK2QUlSiuokF1QIrugQuEOjD5WFwAwYo4ePTrsIaCk+GxBic8XVPhsQYnPF1T4bEGJzxcw2ijcAQAAAAAAAADoAwp3AAAAAAAAAAD6gMIdAAAAAAAAAIA+oHAHAAAAAAAAAKAPKNwBAAAAAAAAAOgDCncAAAAAAAAAAPqAwh1AlCYnJ61SqaR+r9VqWaVSmbm1Wq3cz9vLY7PGMJfnneu4lc+NuWs0Glar1brej88G8mg2myP1GeCzVXxZf4eNjY3xecO8uM/X9PR0x++5W6PR6Pp8/F2JWq1WuM8An63hy8oi9f8z5vnMzuV5R+1zDpQVhTuAKLlFQMgtEiYnJ83si0VWLwucvI/tNIZOzzsxMdHxeec6buVzY+7ca9ytcOezgTxc2e7eJ/e+5f0MZL2/c/kM9PK8WZ8/DFenv8NqtZrV6/WZP/N5w1xUq9XUkit8P6emprqW7qPydyWfr+FxueQ+T2m5NGrrJVUmojfdsmgu8zrPY+fyd6nyM8PnEegdhTuAqIRXRYVqtdqs/2nLe6Vx1mP9RVq3MYTGxsa6jmmu41Y+N+bOXdEyzPePz0Z5hP/TZmY2Pj7eVj50etx8PgOdnjvPY/J8/jAcWX+Hue+5EsEZHx/P/EyY8XlDIvx8he9rpVKxZrPZ9jX3Q8VOnwH+royb+0y5EtCp1+sj/Rkgu4arWxbN57Xv9ti8n9lQns/MXP4e7fa4Xo4PxITCHUA03FVQzaady6oAACAASURBVGZz5n/O0r4f/hTe/bR+amqq63N3euzx48dzjSHteavVauaY8o47vDKin8+N/mk0Glav11MX7f57yGcDeeUp3NM+A93e37y5F35uuz0mz+cPw+Hem7x/hzmNRqOtsODzhjRpn6+0Cxa6vSf8XYk8XC6Z5f9/AOVngOwaHd2yaD6v/Xwe639m0543z2em179H8zx3L39HAzGhcAcQpbSioNOVeZ2uMujlseHXO42h0/OGx/a/nuc+g35uzI1fJnS7SqaX96/XzzSfjXIJt5TJ8098+/H5Ssu9bs87MTHBZ6sgeincx8bGMv9FBZ83hNJKLv8z5195mrWdDOsodOL/MHoQ66VenjtP3vHZGoysH/7N5bWfz2PTLqAIHz+fz0za36N5nnuuf0cDZUfhDiBKaUVBuJ+ek2cB1O2xcy3cw73w0saU5z6Dfm7MTa1Wm/mn8t0K917ev14/03w2ysddeeRu3a406sfnKy33uj3vxMQEn62CyFu4z2XfWYfPW7yyCnf3g2mz7nu4s45CmjCXBrFe6uW58+Qdn63BSMui+bz2882bTn+X9uMz06kUz/MZnsvf0UDZUbgDiBKFO/+jOGqazWbbHocU7uiXer0+q6CqVqu5fskgBSg66eVfaWV91sz4vGG2rMI9LJzc19N+kMg6CqG0XKJwRyejULjn+buUwh0YPRTuAKI01y1l/Kur3K3ZbHZ9LFvKIIsrQP3Xky1l0A/u/eh1T81+fL7Y4qPcuv0d5t6vbr+c178vnzc4WYV7L2UR6yj4/FxK+zpbyiA01y1luv0/Y973rdNnNtSPzwxbygD9ReEOIErD+qWp3caQ9ryqX8jFL/saHWmLcv+W9j9NfDaQx1yvOFL9gix+EVx5ZP0d5t6rbgWBw+cNoblcVZqWZ/xdCcfPpfCHgKP2GSC7Rscwf2lqL3+X9vOXpv7/7d37kyZlYS/wNTmp/APH4+WcqjNF8IaJYXdB0GTWe9bLImeGSyCJKJjMIMjNAOJwWRZEQMWRqLAg4MqsAnLHBJgBRURQIXqi2Qw5x5gL8Yf8lHiqtCqpSu1zflh66Onpy9PvdE/39Hw+Vd9S3p2333777fd53v5OT791l+1LUyGfwh3YkIqKgomJiRV/rld1pnHMffPO7ou9/u3k5GTlOo263m0um9Xp+vWzbwzDag6AYl7fuuNe7H1i9j+6VTSHJftW1WVksuxvpBWVXMlZolU/m2auJGZc6ts+YOzqh6LxZTXbPua+o8ylMfvMKPNo1f3qPD5sJAp3YEOqKgqSs6eKLseQp+59637hXHLmVt5yR13vNpfN6sR8aLdvEGOUa7iHEPf6jrIP1Flu2f5Ht8r+Uiz2zPY0+xtpRSVX9rIyyWuVLeHT+jJX2r+6kR6Xykq/vn1eamtMpJ6isWg17+uq+446l7a5z9gfoT6FO7AhxfwpfJI6HxLq3De2cI9dbtXPJP9edPtqlk3z8gr3vNfQvkGMmZmZZa9Ttpxqcx9oa7+lW3lzWNXlsZLCwv5GlbKz1rOvVcx4Zq7cuKrGpbQu9wFjVz/VGYuaOmass8+Osk7GOlgbCncAAAAAAGiAwh0AAAAAABqgcAcAAAAAgAYo3AEAAAAAoAEKdwAAAAAAaIDCHQAAAAAAGqBwBwAAAACABijcAQAAAACgAQp3AAAAAABogMIdAAAAAAAaoHAHAAAAAIAGKNwBAAAAAKABCncAAKDUwsJCGB8fr8zExETYv39/16sbQghhdnY2LC4uVv5c7HNLkr7P7Oxs208DAIB1RuEOAACUmp2djSqjp6amelG4T01NhYmJiaifjX1uyS8U0veZn59v82kAALAOKdwBAIBSMzMz66pgTsr/UU1MTCydzQ4AAHUo3AEAgFKTk5NhfHy8F2evV1nt5V4WFxdXXdgDALBxKdwBAIBCi4uLYdu2bbWuz56U3nNzc7n/nr4eeggHLgGTvnRLtixPLy97zfX0YyRn4qezsLBQ6/kmy5+Zmcn996SQT/49W/AXrVv20jt5qrYDAAD9p3AHAAAKVRXQeZKSPq8wTq5/Pjc3t1Re5yX9eHNzc6XXVt+3b18IIYTp6encLzmtI71+ebIFe/rn89at7Pbs9qraDgAA9J/CHQAAKBT7paLZgnrbtm25X6KaPls+uVZ6tphPzvROrhmfPnM9/bN55Xhy31ElpX1S4hdtj+TM+fS6pcvx9O3pL3BNCvj0z1Zth7pn6QMA0B2FOwAAUCjvMi15yZbCk5OTKy5Dky6rk+I57yz47FnkyTXksz+bLCNduE9MTKzq+utV16tPtsfi4uLS4+WtW/Jcs790yD63OtsBAID+U7gDAACFkkK5rqSYTpfN6euX513+JZukaC66hnzyGMmZ8MklalbzhalFZ+YnJiYmlp2xnj2DPbtu2V9EZH9JkL1ue9l2AACg/xTuAABArqTAHuWM8eQM7+TSLMl/J+V40TXLs0Vz2TXkk9I+KceTMnvUS7CUnW0eQvEXpuatW7aYT2TPkI/56wGFOwDA+qFwBwAAco3yhamJpLxOF+zp5SRnkscuJ+9LTLNnoyelflJm11X3C1OL1i1bzKdl/2Ig77IzAACsXwp3AAAgV1UBXSYpp+fm5lac1R3CC5eJyUqfVb9///7c+6aXnz77e3p6OneZsZLLuxQV9kVfmJr9gtWya69n/2IguSRNtnBfzV8XAADQHYU7AACQK3uN9LqS0jnvbO9k2enbk6I670tJs/LOLs+eRT/K+pYV9tnyP3tJm0T28jnZ55cu4qu2Q7bMBwCg3xTuAABArsnJyahrjBedFZ6U5XnFcXIGd17SJXrRWd7Z8jv5wtNRr3sec0Z59rrsRV+wWnTme94vCWK3AwAA64PCHQAAWCFbYJel6Kzw5BItZeV3WXFfdmmWvC8lTYruUb44te4XpibbJ++M+snJydzLxBRdHieElV8i68x2AID1SeEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0ACFOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0ACFOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTtAhJmZmTA+Pl6aqampsH///q5Xdc3Mzs6u2AYTExONbYOJiYml5a7ldl1cXAwzMzNr9ngAAADAcCjcASLEFO5J4bwRpMvwvCwsLDT6GGtVuCe/RFC4AwAAAKNQuANEiC3cx8fHw+zsbNer26q8M9vzstqSfK0L94WFhaXHU7gDAAAAo1C4A0RIF+55Z2/Pzc1tmEvLTE9PLz3Xubm5Zf+WLtyz/1aXwh0AAABYbxTuABGqCvcQQm7hni5x01lcXKx8jOxZ9fPz87mPOzU1teKSNul1ycpeDqbuGfnpwj0r/YuHouXGPn5V4V73eeSdmZ/8UiC9DdNJF++Li4th27ZtlY+ZfR2bvtQOAAAA0F8Kd4AIVYV7usxNStp0+RxznfOYy9Zk75N3LfX0benCPa8wLivmY7ZFnbPPFxcXC59X1S8G0o9RtZy89Skq1JPXq6pwL3ttsl8UW/SzG+X6/gAAALCRKdwBItS5hntSiieFcboEThfz2bOji4rs9O3pM67zSv7042aL7HSpnCw75oz0rLLCu+wyMunHT5Q9flHhXnc56X9Lb6f0Lx8WFxcLLymTvj1dmhdt/+zrCAAAAGwcCneACLGFe1VpXXad8PRjpIvrovtMTk7mlrrpn08K93RJXlRs1znLvehSOUXPLfbx08V6XuFetpxke2SfR9ElcJLCPO85pdc/XfDv27cv9zHTy0m/jkP/Al0AAABgOYU7QISqwj3mC0Kzl38pK9zTl45Jl8zpUjo5QzvvUiXZwr3q8jarORu76DI16bI59vGrCvdRnkfZdkorKtzTZ7dnL1eT95rFXO8fAAAAGCaFO0CEvBI1e5Z3tnSvexb4qIV73pnpa1m4p2W/mDTRh8K96gz+qsI97/rw6eercAcAAAAU7gARikrUbAE8Pz8fQlh5nfOk7I29pEybZ7iv5jInZeufSF/CZXFxceTHryrcY5fjDHcAAABgrSjcASKUlajpf0tK3aJiuMnCfdRruBcV5bHSl5DJntWf/QVE3nOIffyqa7jHLqfoGu7Juia/FGjjGu4KdwAAANhYFO4AEapK1HQJPTs7u6x4LirJV1u4py9nkndGdvYyKuniODkTP+aM9bJtUZbs8tKPn3dZnuzP5xXuoywn/VoUfens3NxcYZmfvn/6LPn09k//UkXhDgAAABuXwh0gQlWJmj2ze//+/ZWFdPaa4nUL9xBWfhFr8jN5j7G4uFj4BafZs7+r5D1uNtnLr2Qvs1P1+EWFe9Vyso8bwvKSvux1KPqlQdkvGbKvicIdAAAANi6FO0CEmBI1XRAnRW224N6/f/+yZSWXMyl7jLLCPfu4SXlcVOpnf75omTGKvsC06trqsY9fVLiXLadM9gtd89Y1+0W3Vb+wyF5SJwSFOwAAAGxkCneAgWnyeu0AAAAAxFO4A6xT6TOp08V60bXFAQAAAGiXwh1gnSq6pEvV9cwBAAAAaIfCHWAdK/oC0arrmQMAAADQPIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAOU+MUvfhF+/vOfi4iIiIiIiMga5he/+EXXlQCMROEOUOK5557rZfbu3RuOPeb4MD19epiePj089dTfLCW5rcnbv/fdxVaX7/Zmb3/iyf8d9j728XDdI1Ph6FMOD0efcniYPOV3wvwTf7Em6/O97y72Yju4vf+3n3rqh3u1Pm7v9+2nnvrhXq2P2/t7u88tbq97u/nI7XVuH+J8dMwxx3Z+jFsUpTvrkcIdoMRzzz0Xfv7zn3e9Gitcd9114YKPfiJ896nn1iT33ftMePSRZ9fs8WR1+cJ9u8LH5t69LDN7d4TLb39f64/96CPPhvvufabzbSDrI8YWiY2xRerE2CJ1Y5+R2Ax1Ptq+fUfXh7i5+no8DlUU7gAl+jrBK9ylLBfuPXpF4f6xvQf+9/5vzLf62EM9CJF2YmyR2BhbpE6MLVI39hmJzVDno3/+5//X9SFurr4ej0MVhTtAiT5P8E9//5/X7AOYg5D1k289sS98bO49Kwv35/O1hTtaffyhHoRIOzG2SGyMLVInxhapG/uMxGao85HCHZqlcAco0ecJXuEu33nyH3Jvv+yOPwoXfuWo3DPcF771/VbXaagHIdJOjC0bO0VjWF6MLVInxhapG/uMxGao89EzTz/b9eFtrj4fj0MZhTtAiT5P8Ar3jZtr7r4xnHrL6eGkG04KZ3353DD30IPL/v2uR+5+/rrtR4ULbn330hnvNz5wdevrNtSDEGknxpaNmWvv3xNO+9IZB8awW88NX3rwgcr7GFukTowtUjf2GYnNUOejww8/suvD21x9Ph6HMgp3gBJ9neBdw33j5rI7Ph1OuuGkpbz/hveHk244aUXpfvcj94er75wOF+59b/j47e8Ptz60e03Wb6gHIdJOjC0bL1fe9fnnx64DY9gHbvxAOOmGk8LNf3Fv6f2MLVInxhapG/uMxGao85HCHZqlcAco0dcJXuG+MXPPo99ZVrYvle43fiCc+eWPdL5+331quAch0k6MLRsrDz72w4Ix7P1h+uYPld7X2CJ1YmyRurHPSGyGOh9t376j60PcXH09HocqCneAEn2d4BXuGzO7v357bll10g0nhQ/e9MHw3af+qfN1HOpBiLQTY8vGypcefODAmLV75Rh2yhdPKb2vsUXqxNgidWOfkdgMdT7ypanQLIU7QIk+T/Cu4b7x8pWH558vp963oqz6k5umg8Jd1luMLRsrdz/67cJfGp6scJcGY2yRurHPSGyGOh8p3KFZCneAEn2e4BXuGy9PPvkP4bQvnbF07eN0Pnn32lyjvSpDPQiRdmJs2Xg5+9bzlq7bftLuk8JJuw/8AvHyr82W3s/YInVibJG6sc8MJ9ffPx8u/sqt4Yo77gi3Pfy9xpc/1Pnomaef7frwNlefj8ehjMIdoESfJ3iF+8bMbfOPhNNuOWNZ2X7pHVd3vl5JhnoQIu3E2LLxcvejT4QzvnzOsjFs5quXh28/8ZPS+xlbpE6MLVI39plh5LSbPxve/akzw7s/fdaB//3UmeHjd9zR6GMMdT7ypanQLIU7QIm+TvCu4b6x88QTPw1zDz0Urnvgq+GuRx7vfH3SGepBiLQTY8vGzVcfng9feGBv+Nojj0X9vLFF6sTYInVjn1n/2XXHV5dK9mzumP9+Y48z1PlI4Q7NUrgDlOjrBK9wl75mqAch0k6MLRIbY4vUibFF6sY+s/7zR9dfHnZcc/ayov1dz//vlV+7s7HHGep8tH37jq4PcXP19XgcqijcAUr0dYJXuEtfM9SDEGknxhaJjbFF6sTYInVjn1n/+f3PXbRUsGdL95237W3scYY6H/nSVGiWwh2gRJ8neNdwlz5mqAchsjIL3/q/4fEnfrqqZRhbJDbGFqkTY4vUjX1m/eeML30u53IyZ4R3f+rMcMPXH23scYY6HyncoVkKd4ASfZ7gFe7Sxwz1IEReyE33fyccddXVYfziC8L4xReEP/jsdeGehR+NtCxji8TG2CJ1YmyRurHPrP88+NiPw1HXfGRF6X76zZ9t9HGGOh898/SzXR/e5urz8TiUUbgDlOjzBK9wlz5mqAchciC3P/SDsO3iC8Kbds4sFe7bLvlYeNcnrgjffuIfay/P2CKxMbZInRhbpG7sM8PIg4/tC2ft+Xw4/nMXhZN2fzxcfsftjT/GUOcjX5oKzVK4A5To6wTvGu7S1wz1IEQOZOq6W8KbLnmhbE9n196v116esUViY2yROjG2SN3YZyQ2Q52PFO7QLIU7QIm+TvAKd+lrhnoQIgfy3qs/mVu2v2nnTJi+/ku1l2dskdgYW6ROjC1SN/YZic1Q56Pt23d0fYibq6/H41BF4Q5Qoq8TvMJd+pqhHoTIgXzgczcuu5xMOjNfvqf28owtEhtji9SJsUXqxj4jsRnqfORLU6FZCneAEn2e4F3DXfqYoR6EyIF8/p5vpa7d/sI13N+0cybcNcIXpxpbJDbGFqmTvo8tD37zb8MFX7w//OEnbwnn33hfuH9hX+frtNHT931G+pOhzkcKd2iWwh2gRJ8neIW79DFDPQiRF3LJ3H3Lzmx/++W7wuxd3xhpWcYWiY2xReqkz2PLLfd9P4yfe0U44sxLwpFn7wxHnHlJeOM5l4XP3/mdztdtI6fP+4z0K0Odj555+tmuD29z9fl4HMoo3AFK9HmCV7hLHzPUgxBZnge/+Wy47p7Hw033Pxkef+LvR16OsUViY2yROunz2PKeSz4bjjzr0nDEmQfK9iPO3BmOPPvS8I6ZT3e+bhs5fd5npF8Z6nzkS1OhWQp3gBJ9neBdw136mqEehEg7MbZIbIwtUid9HVseWFh8vmTPT9frt5HT131G+pehzkcKd2iWwh2gRF8neIW79DVDPQiRdmJskdgYW6RO+jq23P3wj5fOas8r3G994C87X8eNmr7uM9K/DHU+2r59R9eHuLn6ejwOVRTuACX6OsEr3KWvGepBiLQTY4vEZtSx5evzz4Y7vv5Xna+/rG36PLa89YJPhiNzCvff/dOPhyef/KfO12+jps/7jPQrQ/2s60tToVkKd4ASfZ7gXcNd+pihHoRIOzG2SGzqji177/1hOOq868LWD1watn7g0vCGP7kiXH3Lo50/D1mb9HlsufaOby8r2o8868D/XrX3kc7XbSOnz/uM9CtD/ayrcIdmKdwBSvR5gle4Sx8z1IMQaSfGFolNnbHl8W//fXjz6deEw0/etVS4H/b8/7/+9ic7fy7Sfvo+tsx9/Qfhj2fnwjsv+kw45TNz4eZ7v9/5Om309H2fkf5kqJ91n3n62a4Pb3P1+XgcyijcAUr0eYJXuEsfM9SDEGknxhaJTZ2x5fIvPrxUtKdz2MmXhhMuvrnz5yLtx9gidWOfkdgM9bOuL02FZincAUr0dYJ3DXfpa4Z6ECLtxNgisakztkxfdVt4/SmX5ZTuO8PvTH0iPNWD5yPtxtgidWOfkdgM9bOuwh2apXAHKNHXCV7hLn3NUA9CpJ0YWyQ2dcaWXTcWn+F+3IVfVLhvgBhbpG7sMxKboX7W3b59R9eHuLn6ejwOVRTuACX6OsEr3KWvGepBiLQTY4vEps7Y8o3H/i5s+9DVy6/h/oED//9zX3kiahm7Pvdw+KOP7gknfOTm8NFPPdD585d6MbZI3dhnJDZD/azrS1OhWQp3gBJ9nuBdw136mKEehEg7MbZIbOqOLbfc9f3wrnP+bKlwf/0pl4WPf3E+6r5/9NE9YfPkrrD12MvD1mMvC5snd4V3n/q5zreBxMfYInVjn5HYDPWzrsIdmqVwByjR5wle4S59zFAPQqSdGFskNqOOLXf9xY/DrXf/ZfjOE/8Y9fOfvOEbYfPkrrD5mF0H/ndyV9g8eWnYPLkrfOTKezrfDhIXY4vUjX1GYjPUz7rPPP1s14e3ufp8PA5lFO4AJfo8wSvcpY8Z6kGItBNji8RmrcaWUy+9PWw99vJU2X4gW47ZFd7xwc92vh0kLsYWqRv7jMRmqJ91fWkqNEvhDlCirxO8a7hLXzPUgxBpJ8YWic1ajS2nXXZH2HrMrhWF+9ZjLwtHn35959tB4mJskbqxz0hshvpZV+EOzVK4A5To6wSvcK+XBx/623DdTU+GO+/5UefrMvQM9SBE2sl6H1tk7bJWY8tnbnpsRdme5LxP3tf5dpDqfOWOH4ZPXftQuP+Bv+p8XWT9xHwksRnqZ93t23d0fYibq6/H41BF4Q5Qoq8TvMI9PmddeGc49G2XLmXyg9eHO+9VvLeVoR6ESDtZz2OLrG3Wcmw5+cJbD5zVfsxlYcvzZ7sfffruzreBlOeGPU+Gtx//mWVz/sVX/nnn6yXrI+Yjic1QP+v60lRolsIdoESfJ3jXcK/Oxz7+wIGD7re/cPC9+e27wlHv/0J4qgfrN8QM9SBE2sl6HVtk7bPWY8uVux8NH7xob3j/x24Nl8w+2Pnzl/IsPPKT8MajPhE2v2PXgfn+rTvDoW8/8P8/c/1jna+f9D/mI4nNUD/rKtyhWQp3gBJ9nuAV7tX53fdeHTY/f8D9QnaGQ992abhp7nudr98QM9SDEGkn63VskbWPsUXKcvk1D2fm+gPZ8o5d4dg/vrHz9ZP+x3wksRnqfPTM0892fXibq8/H41BG4Q5Qos8TvMK9PN/45k9yD74Pfdul4bffeml46snu13GIGepBiLST9Ti2SDcxtkhZTvvobTm/YD/wF25HvmftLsEn6zfmI4nNUOcjX5oKzVK4A5To6wTvGu5xefPkpwtL9z1ffbrz9RtihnoQIu1kvY4tsvYxtkhZrvzsIyt/uf62nWHz23eFE069qfP1k/7HfCSxGep8pHCHZincAUr0dYJXuMflitn55w+8dy27lvsJp97c+boNNUM9CJF2sl7Hlr7nW4/9NJx+5lfDUf/r2nDs8V8IMxfe2/k6rTbGFqnKO35/NmzOfGfLoW+7NNz45ac6Xzfpf8xHEpuhzkfbt+/o+hA3V1+Px6GKwh2gRF8neIV7fHZ98sFw+Ls+vnQA/sGPzIVHv/GTztdrqBnqQYi0k/U8tvQ133rsp+Gtb78qbD7sorDl9ReFra+/OGw+7KJw4h/e0Pm6rSbGFqnKXff+KBz3JzcuzfdvPOrKMHv9tzpfL1kfMR9JbIY6H/nSVGiWwh2gRJ8neNdwr5e77vtx+Pbj/9D5egw9Qz0IkXYyhLGlb/nwWV8Nmw+7KGzeetGB/03l6k8tdL5+o8bYIrF55NGfhFv2PG5skVoxH0lshjofKdyhWQp3gBJ9nuAV7tLHDPUgRNqJsaX5HDVxbdjy+pVl+9bXXxxO+/Bc5+s3aowtUifGFqkb+4zEZqjz0TNPP9v14W2uPh+PQxmFO0CJPk/wCnfpY4Z6ECLtxNjSfI457gvh8CN3rijctxx2UfjT877W+fqNGmOL1ImxRerGPiOxGep85EtToVkKd4ASfZ3gXcNd+pqhHoRIOzG2NJ+LLr5/Rdm++bALw+bDLgq7dz/R+fqNGmOL1ImxpTxfv++vw599+tHwhc9+Mzz054udr08fYp+R2Ax1PlK4Q7MU7gAl+jrBK9ylrxnqQYi0E2NLO/nD991w4Kz2ww9k82EXhbPOub3z9VpNjC1SJ8aW4lxywb1hyyvOXcrhrz4/XLHz652vV9exz0hshjofbd++o+tD3Fx9PR6HKgp3gBJ9neAV7tLXDPUgRNqJsaW9fPqaR8MZZ90Wzj3/znV9ZnsSY4vUibElP7s/961lZfuWV5wbthx8XtjyinPDl2/6bufr12XsMxKboc5HvjQVmqVwByjR5wneNdyljxnqQYi0E2OLxMbYInVibMnP1PtuDoe/+qMrSvetrzwvnH3q3s7Xr8vYZyQ2Q52PFO7QLIU7QIk+T/AKd+ljhnoQIu3E2CKxMbZInRhb8jP5rs+Ew151fm7h/r7JL3S+fl3GPiOxGep89MzTz3Z9eJurz8fjUEbhDlCizxO8wl36mKEehEg7MbZIbIwtUifGlvycdepc2PKK81ZeVuYV54aPfeRrna9fl7HPSGyGOh/50lRolsIdoERfJ3jXcJe+ZqgHIdJOjC0SG2OL1MkoY8sVF9wT3nvEpeGN//PMcNy2T4QvRkGOqgAAGTBJREFUXvtY58+j6fzFA38T3vDamXDYK18o3be+4rzwpq07wzcf/bvO12+97TOyMTPU+UjhDs1SuAOU6OsEr3CXvmaoByHSTowtEhtji9RJ3bHl3D/+Utjy4umw5cWnhi0vng6HveRDYcuLp8Pnr5zv/Lk0ndv2/mWYfOc1YesrzguHvfL8cMJ7rw333Pmjzter65iPJDZDnY+2b9/R9SFurr4ej0MVhTtAib5O8Ap36WuGehAi7cTYIrExtkid1Blb7r/7R2HLi6fD1v926vOl+4FsfcmHwltedW7nz6WtfOeJf+x8HfoU85HEZqjzkS9NhWYp3AFK9HmCdw136WOGehAi7cTYIrExtkid1Blb/uzKh5YV7em8/r+f3vlzkbWJ+UhiM9T5SOEOzVK4A5To8wSvcJc+ZqgHIdJOjC0SG2OL1EmdsWXP9d8OW148HTa/eGpF4b71JR8KTz3Z/fOR9mM+ktgMdT565ulnuz68zdXn43Eoo3AHKNHnCV7hLn3MUA9CpJ0YW7rNzdc+Gi6aviVcdd7Xwv1f+2Hn61MWY4vUSd2x5W2HnB+2vvRDYct/TS4rc6B8/8CO2c6fS9e55c++ES750JfDJ/70tnD3V4b7HjQfSWyGOh/50lRolsIdoERfJ3jXcJe+ZqgHIdJOjC3d5Y/fdVX4rU3HLOXQXz8+XH72Vzpfr6IYW6RO6o4tu695NIwfdPbzZfuBL0w9+ohd4aEHFjt/Ll3m1KM+vWyc+K1Nx4SLT93T+Xr1YZ+RjZuhzkcKd2iWwh2gRF8neIW79DVDPQiRdmJs6SYXTd3yfHk2uaxIe92mY8Pte77X+frlxdgidTLK2PLo/P8JV198f/jIybeEa694sPPn0HUuO3NuRdme5Nbdj3e+fn3YZ2RjZqjz0fbtO7o+xM3V1+NxqKJwByjR1wle4S59zVAPQqSdGFu6yXsOOSf89q8cl1uk9fXsVWOL1ImxZfWZPOyCcOivH587Tpz3/t2dr1/Tsc9IbIY6H/nSVGiWwh2gRJ8n+LW8hvtrD3lzuOrKWzv/ICj9z1VX3hpee8ibO18PWR/5zde+xdjSQcZfdkpuifa6TceGM4+7tvP1y0sytjz15D91vi7S//jcsvq84zdOC6/bdOyKceK3Nx0Xpo/6ZOfr13TsMxKboX7WVbhDsxTuACX6PMGvZeH+ok0vDyeecE7nHwSl/znxhHPCiza9vPP1kPWR//IiY0sXOfF3LgmH/trxKy4p81ubjgnXXHhv5+uXu87Pjy0Kd4mJzy2rz8nvuCK8blP+X8J84k9v63z9mo59RmIz1M+6zzz9bNeHt7n6fDwOZRTuACWee+65cMYZZ4Szzz67d3nvUSeHHTtODu896oPhxBPOCSeecE74/ePPCjt2NH/7iza9PPzma9/S2vLdPpzbf/O1bwkv2vTy3qyP2/t9+4s2vSS88pVv6M36bJTbj3rnVHjZpsPCS3/l0PCSTa8LL9n02+Flmw4Pr37523q1nunbX/nKN4QXbXpJb9bH7f2+3eeW1d/+jrf+QXjprx0aXrrp0PCyTYc/n8PCQS9+Y6/Ws6nbzUduj719qPPRy1/+Pzo/vs3L3r17Fe6sSwp3gBL33HNP2LRpU0/zK6n8Wipud7vb3e52t7vd7W53u9vd7na317m96+PblTn88MPDf/7nf3ZdC0BtCncAKm3atCl89Pzzu14N1oGPnn9+2LTJxwvi/Oqv/qqxhSjJ2LJ///6uV4V1YNOmTeF8Yws12GeI5bMuEMMoAUAlhTuxHIRQh8KdWAp36lCeUpd9hlg+6wIxjBIAVFK4E8tBCHUo3ImlcKcO5Sl12WeI5bMuEMMoAUAlhTuxHIRQh8KdWAp36lCeUpd9hlg+6wIxjBIAVFK4E8tBCHUo3ImlcKcO5Sl12WeI5bMuEMMoAUAlhTuxHIRQh8KdWAp36lCeUpd9hlg+6wIxjBIAVFK4E8tBCHUo3ImlcKcO5Sl12WeI5bMuEMMoAUAlhTuxHIRQh8KdWAp36lCeUpd9hlg+6wIxjBIAVHr44Ye7XgXWEfsLsewr1GF/IZZ9hbrsM9RhfwGqKNwBAAAAAKABCncAAAAAAGiAwh0AAAAAABqgcAcAAAAAgAYo3AEAAAAAoAEKdwAAAAAAaIDCHaAnFhYWwvj4eNi/f/+Kf5ubmwvj4+NLmZubi15unfsm69DkskdZ97aWy3IzMzNhYmIi6me91hvT7Oxsr15T+0v/lM0bk5OT9h+WlO0ryb8lmZmZiVqmuWmYJiYm1t04YJ9pXtmY0faxkfkLWC2FO0BPJB+OsoV78uFpfn4+hPDCh886H/xi75usQ4yYZSc/s7CwEL3uMfcZZbksl2yzmMK9rdekznJH2f9ZnaRsT16f5LXo6v1rbOinonljYmIiTE1NLf130/tP3THBeNO9on0l+9osLi6Gbdu2VZbu5qZhihk7VjuP+Oy6PsSOGaMcG5Xd1/wFNEHhDtCx7Fld2cJ9cnJyxUFn7JnJsffNrkOMmGVPTEzUXveY+5T9TN5fCLBScvZYzH7U1msSsw+tZv9ndbIHnCGEMDU1teK27H3aev8aG/qlbN5I/i058E9MT0+XvhYxr9+oY0Kby6Zc1WeM8fHxMDs7u+y25Bd+bY4JoyzXvtKuZF9JisXE1NRUI2N9F59d7TP1VY0Zo7xGsfcddf4qe33NX7AxKdwBOrS4uLh0oJl3cJmc5ZU9OyE5i2FxcbF02TH3TX4uvQ4x61217OS5VT1++qyRmPtU/cy+ffsq13+jm5mZCVNTU7kfxLNn8TT5mmRf65h9aNT9n9WLKdzbev+2uR+yenlzV4yZmZll81yd/Wffvn3RY0Ld/afOsqmnal9Jyq2q92cbY8Ion0PsK91Ixo4Q4t7P6f9O7zNdfHa1z9RTNWbEvkZlyx7lvtn5K7vcstfX/AUbk8IdoCfyCveiM32Kbo/5mbL7xhYnMcse5fGLziqps9zsfVku2U6Li4tRZ7609Zq0tQ/RnOwlZar+PLnN92+d/aXo8Y0N7ahTuE9OToapqancwiJm3xh1TGhz2cTL21fSn33SZ7RWXU6miTFhlM8h9pVupH8BPOpYb59Zf8p+SbeaY6M6r2/C/AXUpXAH6Im8wj17zb5EzAeoUe4bW5zELHuUx89ef3CU5SrVyk1MTCz96X5M4d7Wa9LWPkSzkjOrkpSdJdXm+7fO/qJwX1t1542iX9jE7BujjgltLpt4ZYV7enyJuYZ7E2PCKJ9D7CtrLzt2jDrW22fWn7wxo4ljo7qFu/kLGIXCHaAnFO4K97bNzs4uK9gV7pSZmppaUYKNjxefeapw35hi5o3kNVhNgaqwWP/KCvdskZXcXnSpGeXpxpA3dijcN44+FO7mL2BUCneAnhj1kjLps8OSzM7ORt23aB2qxCx7lMcvOliqs1ylWr6kLE1vN5eUoUiyjetcD7TN92+d/UXhvraq5o1k+xf9KX7258r2jVHHhDaXTbyywt3lQchKjx15t9tnhm/US8pUHRvFvr7mL2A1FO4APdHVl6bmrUOVJr94Krvcqvv4YsTR5B18pFN0gNrWa+JLU/ttlLOl2nz/Ghv6q2zeSLZ9tjDL0+YXw/nSuX4oO1u1bnna5Jem1lmufWVtpMeObNG5mnmki8+u9pnRdfmlqXXnr6a+NLXuOtu/oL8U7gA9kVe4h3DgS3qyf8YYc2byKPet++V3VcuemJiove4x9yn7mbIzUFgudj9q6zWJ2YdWs/8zulEPaNt8/xob+qlo3kj2laovv0yLef1GHRPaXDZxysqz5LtFsj/b5pgwynLtK+2LGTtGHeu7+Oxqnxld0fwyymtU576jzF9lr6/5CzYmhTtATxQdXGbP/iq61EOeuvetU7jHLDt7lmzMusfcZ5TlslLsB/G2XpM6yx1l/2d16l7DPYR237/Ghn4qK1FjzgxMa3NMMN50r+gzRnJ79rXJlvBZ5qbhiR07VjuP+Oy6PlT9QneUbVl1X/MX0BSFO0BPlJ3NlXyISlLnw1Od+9Yp3GOXXfUzyb/nfWhczXKplle4570e6du91hvLzMzMsm2fLcDaek3b3A9pVtl1uYuSzHP2n40l5vJDdcaavPuZm9a3qrEjrctxwD6zNuqMGU0dG8XOX6Ouk/kLNg6FOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0ACFOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAQIlt27aF8fHxFZmYmOh61XIl67t///6uVyUsLi5GrU+yTRcXF6N+ZnFxcem/hyLZTvv27et6VaKl3w9zc3O17tNHa7lfrfU+3Oft3rShPtc+je190OZ7aL1ta+MJ9I/CHQAAShQV7km6Lkinp6eXlZ19KgoU7vHWW+E+MzOz7H0wPz+f+3NTU1PL9s8+v25rsV8l79eNWJBlx6q29OG5NqHPY3sfNP0eSo9V621bD3E8yc4dsN4o3AEAoERRETo5ORnGx8fD1NRUR2t24IA0e3bxeisKQlC4h7D+Cvfp6enKM9vz9s8+v25t71d522OtdL3d1/K5d/1cmzCUsX29yG5v27pc2++xLsdKaIrCHQAAShQVoXnlXPLf6bN/FxYWwsLCwooz4xcWFlY8VlLiJ8VyWRGdFJ7ZS9yki4L0v2eXkT1DuezAdm5ubumXC+n7hRDC7Oxs4XMqOsN9YmJi2ePmrWPZz5QVo3WeVyL9HJLXL63odS0Ssw5Fzy+9n6V/Zt++fbnbqeqx0svOe4xRtklShqT3vWwxVbR/pl+39F+PrGb/LHqeee+bsuWudr/Kbpf042e3RzpZVftjst3m5+ejX9e8fS2vUCx77OS+6ctpJfto2etTtC9UPc8iZds5/VzT/z+7ffLG5OxfaSTbOfuz2cdr4n0as73aGNvT22iUeSt9e+w2Ss8L6dek7nqXzcFV65OWN56l3x9l77FRx6m6c2nVa1E0dhWNFWXbI2+btP0ey27HvP0f1huFOwAAlCg78zg5ME8OfPMOFNPlQjZFJXQ2oxTu2eWlD1qLDm5nZ2dzt0FemVn0GOnnlFe4p3+pUPQ8q7ZFUblQ93mV3Sf9lwt1CoCYdSh7fsl+FrOdqh4rvZ3qFBhl22T//v2NFO5l+07d17HoPZZdrzrbq+5rmt0m2eXEFu4x++Mo3ytR9Ngx40Lyuqefx+zs7FJBWPVXPnn7QszzjFlWkvTrXLaPhVD8vsi+FjHbuYn3acz2Sq9Pk2N7enull1e2jfK2ddl7L2a8G2W9ywr3svXJKivcm97WdebSvOdZ9FpUFe5l+3BWl++xiYmJ3NcD1iOFOwAAlCgr3JMDw2zhXlUSZJeZPhMsKWmKzvzOe/y8yw4k65BedvL4eQexeQfDiey6pJe5sLCw7OC6rHBP3y957mXLLvqZvHIheaw6zyu9fsmZd+ll13ldy7Zt0TbIe6337dtXaxuUPd/02ZSx8p5/3nZa7SVl8vbP/fv3L3sd8wqePOnnWVSqxWyvqv2qaH2y77EQXijj8kr5omu4p7dzettnX4+q93ie5N/zXovs+pS97nlFWoyi5172PLOy+0rRdi7bx/IU/TVR1XZu6n1atb1i12fUxxp13sq7b/Y1ihnvRnnPp59v+meq1qdI0SVlmt7WZWP9/Pz8su1c9ryzr0VV4R77Xuj6PZZwSRmGQOEOAAAlRjnDvagwyp7NlS1pii5lMkrhnleKLC4uFp5hV7bu2eK2rOhIP262cI95njE/k/f4q31eeWdCJyVA1esauw7z8/OFzy/9utXZTlXPN3t7WSmd3SZp2W2y2sI9r3RJP/c6r2N6Gennmfe8ypY76n5V9HqVbY+yx6ra9lXv8Tx5ZVh6ubGPnd0msYVY+rnXeay02O2cty2Ktk/29czbL4uW0+T7tGx7ZdenybE9vYyqf09Std/FjGVNvOfL5qGi9SlSVLg3va2zc07eX4Hl7XdVr0VV4R47VnT1HstuL4U7Q6BwBwCAEmUH6zEH+2UH1NnCPVtAVZVosV+st9qioKhwT5/dl1fGFBXu2dI3b/3Kfqarwr3qurd1Cvfsa51XQMVsp9jnW1Z6FG2TtKYL96rnXrfIyi4ruz8OsXAv2jfy5G33UQv39KU06l53fS0L97zbisaPvO2Xd6Zx3bGqjcK96cfKe+5526isvE0rGsuqfqbuepe9jkWPVSTmS1Ob2NZFhXv67P5s4R7zWlQV7rFjRVfvsey6KNwZAoU7AACUKDpYTwrHvGt9pw8ek+scJweweX+ynfdn9+kvUGuycC/6U/gyTRXuXVxSpkzdS8pUFe4x23bUS8pk94dRXscQqouMtbqkTFr6PVZ0eYm6susXs73qXFImreySMnlfNtvUJWVGKdzzLgtR55IysV8AndX2JWXS27mqDCwbk9OqCve1fp+2MbZnl5GImbfS901Lv5+r5rbVvOe7LNxH3dajFO4xr0VThXtX7zGFO0OkcAcAgBJFXzqWLVpCKC8uqu6b9+VjVSVa+svFsl+sV3aAXfQFj0XlQVOFewjtfmlq0Ze9jfIlp1W/SClStm3rfIlgdjvl7Q9Vr2PZWZhlz6XOl2fGFO7pdYopxOq+jmXPM70/Vm2v1exXRctOb+eqL1at2vbZ7TVK4V72HGJe92S/TJ+pHlM6ZveFpr80teqs6/T2KRuT65zhnt4eq3mfxmyv9Po0ObbnLSOE+Hkr5v1cNreN+p4PoZ3CPbt+TW/r1RTuZa9FU4V7CN28x4oK99jxBfpI4Q4AACWKCve8g8CiA9n0Aezc3NxS2ZQtK9OPlV5ekfRZY3VKmRBWlmtl1/ZusnAPYXkBU/TlsGU/U1QuFD2vKtlyIHtJi6qCYpR1KHp+eaVGsv3ynnPVY+WV0WXFU+w2iSnc8/bP2EKs7uuY9zzzXq+y5dbdr7Lvl2wBl338vLPD8x6ratuvpnDPbqfscyh77LwzXfNuy5O3L1Q9zyJV2zlvu2Z/Nr2MojE5pnBP37aa92nM9mpjbC9aRuw2in0/Z/f3vOdSd72bLNyz2zvv/RG7rcuMUriHUP1aNFm4Zx9vLd5jZWOlwp31SuEOAAAdSx8sJwejRX+CzfClf1Fhf4B+8j6tVjW3reayUQB9pnAHAIAeKLrMSOyXEjIsRZfesT9Af3ifVjO3ARuRwh0AAHoie/mamMuhMFzZgqrqEgvA2vM+rZa3jQCGTOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0ACFOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0ACFOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0ACFOwAAAAAANEDhDgAAAAAADVC4AwAAAABAAxTuAAAAAADQAIU7AAAAAAA0QOEOAAAAAAANULgDAAAAAEADFO4AAAAAANAAhTsAAAAAADRA4Q4AAAAAAA1QuAMAAAAAQAMU7gAAAAAA0IB1XbifeOKJYWxsLIyNjYUTTzyx69VpxZ133hl+4zd+I1x55ZXR9xny9gAAAAAA6KvWC/df/vKXYefOneGII44IBx100FJB/prXvCYcffTR4ac//enIyx5i4X7nnXeGsbGx8Pjjjy/993oq3MfGxsLOnTsL//1nP/tZePOb31z4Mz/72c/CCSecEF71qleFsbGxcNBBB4Xf+73fC3/9139duMyrrroqvOY1rwljY2Ph4IMPDieffHL45S9/WfjzDz/8cHjTm960tO+86lWvCnv27Kn1PNqwc+fOcMghh4R/+Zd/WdPHBQAAAACa0Wrhftddd4WDDz54qdjMy2233Tby8odWuP/rv/5rOOSQQ8I5Z5+9quX0sXD/t3/7t3D66acv/dKlqMw++OCDw8EHHxxOO+20sGfPnnD66aeHgw8+OBx00EHhBz/4wYqfT/aBo48+OuzZsyeccMIJYWxsLIyPj4d///d/X/HzU1NTYWxsLBx55JHh6quvDnv27AnHH3/8il9odFG4hxDC+Ph4OO6449b8cQEAAACA1WutcL/ttttKi3aF+0rnnH12ePWrX51bFNfRt8L9tNNOWzpb/Z3vfGdpmT09PR3+4z/+Y9ltP/jBD8LY2FiYmJhYdvsDDzyQu6ydO3eGsbGxcNVVVy27fffu3WFsbCzMzMyM9DzWwuOPPx7GxsbCgw8+uOaPDQAAAACszv8HuxJdwNTI6SgAAAAASUVORK5CYII="
                }
            },
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Example output from pipelined functions\n",
                "\n",
                "This is what the pipelined functions should output (although the results\n",
                "will obviously not be the same for your environment).\n",
                "\n",
                "![image.png](attachment:0f98df03-f8db-4ddc-a8cd-2535ff315af5.png)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Adding custom functions to the pivot interface\n",
                "\n",
                "To do this you need the following information\n",
                "\n",
                "| Item                   | Description                                                                 | Required    |\n",
                "| :--------------------- | :--------------------------                                                 | :---------- |\n",
                "| src_module             | The src_module to containing the class or function                          | Yes         |\n",
                "| class                  | The class containing function                                               | No          |\n",
                "| src_func_name          | The name of the function to wrap                                            | Yes         |\n",
                "| func_new_name          | Rename the function                                                         | No          |\n",
                "| input type             | The input type that the wrapped function expects (dataframe iterable value) | Yes         |\n",
                "| entity_map             | Mapping of entity and attribute used for function                           | Yes         |\n",
                "| func_df_param_name     | The param name that the function uses as input param for DataFrame          | If DF input |\n",
                "| func_df_col_param_name | The param name that function uses to identify the input column name         | If DF input |\n",
                "| func_out_column_name   | Name of the column in the output DF to use as a key to join                 | If DF output|\n",
                "| func_static_params     | dict of static name/value params always sent to the function                | No          |\n",
                "| func_input_value_arg   | Name of the param that the wrapped function uses for its input value        | No          |\n",
                "| can_iterate            | True if the function supports being called multiple times                   | No          |\n",
                "| entity_container_name  | The name of the container in the entity where the func will appear          | No          |\n",
                "\n",
                "\n",
                "The entity_map controls where the pivot function will be added. Each entry\n",
                "requires an Entity name (see msticpy.datamodel.entities) and an entity\n",
                "attribute name. This is only used if an instance of the entity is used\n",
                "as a parameter to the function. For `IpAddress` in the example below,\n",
                "the pivot function will try to extract the value of the `Address` attribute\n",
                "when an instance of IpAddress is used as a function parameter.\n",
                "\n",
                "```yaml\n",
                "  entity_map:\n",
                "     IpAddress: Address\n",
                "     Host: HostName\n",
                "     Account: Name\n",
                "```\n",
                "\n",
                "This means that you can specify different attributes of the same entity\n",
                "for different functions (or even for two instances of the same function)\n",
                "\n",
                "The `func_df_param_name` and `func_df_col_param_name` are needed only if\n",
                "the source function takes a dataframe and column name as input parameters.\n",
                "\n",
                "`func_out_column_name` is relevant if the source function returns a\n",
                "dataframe. In order to join input data with output data this needs to\n",
                "be the column in the output that has the same value as the function\n",
                "input (e.g. if you are processing IP addresses and the column name\n",
                "in the output DF containing the IP is named \"ip_addr\", put \"ip_addr\" here.)\n",
                "\n",
                "When you have this information create or add this to a yaml file\n",
                "with the top-level element `pivot_providers`.\n",
                "\n",
                "Example from the msticpy ip_utils `who_is` function\n",
                "```yaml\n",
                "pivot_providers:\n",
                "  ...\n",
                "  who_is:\n",
                "    src_module: msticpy.sectools.ip_utils\n",
                "    src_func_name: get_whois_df\n",
                "    func_new_name: whois\n",
                "    input_type: dataframe\n",
                "    entity_map:\n",
                "      IpAddress: Address\n",
                "    func_df_param_name: data\n",
                "    func_df_col_param_name: ip_column\n",
                "    func_out_column_name: ip\n",
                "    func_static_params:\n",
                "      whois_col: whois_result\n",
                "    func_input_value_arg: ip_address\n",
                "```"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Once you have your yaml definition file you can call\n",
                "```python\n",
                "    Pivot.register_pivot_providers(\n",
                "        pivot_reg_path=path_to_your_yaml,\n",
                "        namespace=globals(),\n",
                "        def_container=\"my_container\",\n",
                "        force_container=True\n",
                "    )\n",
                "```\n",
                "\n",
                "Note, this is not persistent. You will need to call this each time you\n",
                "start a new session."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### register_pivot_providers docstring\n",
                "\n",
                "```python\n",
                "Pivot.register_pivot_providers(\n",
                "    pivot_reg_path: str,\n",
                "    namespace: Dict[str, Any] = None,\n",
                "    def_container: str = 'custom',\n",
                "    force_container: bool = False,\n",
                ")\n",
                "Docstring:\n",
                "Register pivot functions from configuration file.\n",
                "\n",
                "Parameters\n",
                "----------\n",
                "file_path : str\n",
                "    Path to config yaml file\n",
                "namespace : Dict[str, Any], optional\n",
                "    Namespace to search for existing instances of classes, by default None\n",
                "container : str, optional\n",
                "    Container name to use for entity pivot functions, by default \"other\"\n",
                "force_container : bool, optional\n",
                "    Force `container` value to be used even if entity definitions have\n",
                "    specific setting for a container name, by default False\n",
                "```"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 46,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "\u001b[1;31mSignature:\u001b[0m\n",
                        "\u001b[0mPivot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mregister_pivot_providers\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m\n",
                        "\u001b[0m    \u001b[0mpivot_reg_path\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
                        "\u001b[0m    \u001b[0mnamespace\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
                        "\u001b[0m    \u001b[0mdef_container\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'custom'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
                        "\u001b[0m    \u001b[0mforce_container\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mbool\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
                        "\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
                        "\u001b[1;31mDocstring:\u001b[0m\n",
                        "Register pivot functions from configuration file.\n",
                        "\n",
                        "Parameters\n",
                        "----------\n",
                        "pivot_reg_path : str\n",
                        "    Path to config yaml file\n",
                        "namespace : Dict[str, Any], optional\n",
                        "    Namespace to search for existing instances of classes, by default None\n",
                        "def_container : str, optional\n",
                        "    Container name to use for entity pivot functions, by default \"other\"\n",
                        "force_container : bool, optional\n",
                        "    Force `container` value to be used even if entity definitions have\n",
                        "    specific setting for a container name, by default False\n",
                        "\n",
                        "Raises\n",
                        "------\n",
                        "ValueError\n",
                        "    An entity specified in the config file is not recognized.\n",
                        "\u001b[1;31mFile:\u001b[0m      e:\\src\\msticpy\\msticpy\\init\\pivot.py\n",
                        "\u001b[1;31mType:\u001b[0m      function\n"
                    ]
                }
            ],
            "source": [
                "Pivot.register_pivot_providers?"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### Adding ad hoc pivot functions\n",
                "\n",
                "You can also add ad hoc functions as pivot functions. This is\n",
                "probably a less common scenario but may be useful for testing and\n",
                "development.\n",
                "\n",
                "You can either create a PivotRegistration object and supply that (along\n",
                "with the `func` parameter), to this method."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 47,
            "metadata": {},
            "outputs": [],
            "source": [
                "from msticpy.init.pivot import PivotRegistration\n",
                "\n",
                "def my_func(input: str):\n",
                "    return input.upper()\n",
                "\n",
                "piv_reg = PivotRegistration(\n",
                "    input_type=\"value\",\n",
                "    entity_map={\"Host\": \"HostName\"},\n",
                "    func_input_value_arg=\"input\",\n",
                "    func_new_name=\"upper_name\"\n",
                ")\n",
                "\n",
                "Pivot.add_pivot_function(my_func, piv_reg, container=\"change_case\")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Alternatively, you can supply the\n",
                "pivot registration parameters as keyword arguments:"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 48,
            "metadata": {},
            "outputs": [],
            "source": [
                "def my_func(input: str):\n",
                "    return input.upper()\n",
                "\n",
                "Pivot.add_pivot_function(\n",
                "    func=my_func,\n",
                "    container=\"change_case\",\n",
                "    input_type=\"value\",\n",
                "    entity_map={\"Host\": \"HostName\"},\n",
                "    func_input_value_arg=\"input\",\n",
                "    func_new_name=\"upper_name\",\n",
                ")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Saving and re-using pipelines as yaml\n",
                "\n",
                "```yaml\n",
                "pipelines:\n",
                "  pipeline1:\n",
                "    description: Pipeline 1 description\n",
                "    steps:\n",
                "      - name: get_logons\n",
                "        step_type: pivot\n",
                "        function: util.whois\n",
                "        entity: IpAddress\n",
                "        comment: Standard pivot function\n",
                "        params:\n",
                "          column: IpAddress\n",
                "          join: inner\n",
                "      - name: disp_logons\n",
                "        step_type: pivot_display\n",
                "        comment: Pivot display\n",
                "        params:\n",
                "          title: \"The title\"\n",
                "          cols:\n",
                "              - Computer\n",
                "              - Account\n",
                "          query: Computer.str.startswith('MSTICAlerts')\n",
                "          head: 10\n",
                "      - name: tee_logons\n",
                "        step_type: pivot_tee\n",
                "        comment: Pivot tee\n",
                "        params:\n",
                "          var_name: var_df\n",
                "          clobber: True\n",
                "      - name: tee_logons_disp\n",
                "        step_type: pivot_tee_exec\n",
                "        comment: Pivot tee_exec with mp_plot.timeline\n",
                "        function: mp_plot.timeline\n",
                "        params:\n",
                "          source_columns:\n",
                "              - Computer\n",
                "              - Account\n",
                "      - name: logons_timeline\n",
                "        step_type: pd_accessor\n",
                "        comment: Standard accessor with mp_plot.timeline\n",
                "        function: mp_plot.timeline\n",
                "        params:\n",
                "          source_columns:\n",
                "              - Computer\n",
                "              - Account\n",
                "  pipeline2:\n",
                "    description: Pipeline 2 description\n",
                "    steps:\n",
                "      - name: get_logons\n",
                "        step_type: pivot\n",
                "        function: util.whois\n",
                "        entity: IpAddress\n",
                "        comment: Standard pivot function\n",
                "        params:\n",
                "          column: IpAddress\n",
                "          join: inner\n",
                "      - name: disp_logons\n",
                "        step_type: pivot_display\n",
                "        comment: Pivot display\n",
                "        params:\n",
                "          title: \"The title\"\n",
                "          cols:\n",
                "              - Computer\n",
                "              - Account\n",
                "          query: Computer.str.startswith('MSTICAlerts')\n",
                "          head: 10\n",
                "      - name: tee_logons\n",
                "        step_type: pivot_tee\n",
                "        comment: Pivot tee\n",
                "        params:\n",
                "          var_name: var_df\n",
                "          clobber: True\n",
                "```"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 49,
            "metadata": {},
            "outputs": [],
            "source": [
                "from msticpy.init.pivot_core.pivot_pipeline import Pipeline\n",
                "\n",
                "pipelines_yml = \"\"\"\n",
                "pipelines:\n",
                "  pipeline1:\n",
                "    description: Pipeline 1 description\n",
                "    steps:\n",
                "      - name: get_ip_type\n",
                "        step_type: pivot\n",
                "        function: util.ip_type\n",
                "        entity: IpAddress\n",
                "        comment: Get IP Type\n",
                "        params:\n",
                "          column: IPAddress\n",
                "          join: inner\n",
                "      - name: filter_public\n",
                "        step_type: pd_accessor\n",
                "        comment: Filter to only public IPs\n",
                "        function: query\n",
                "        pos_params:\n",
                "          - result == \"Public\"\n",
                "      - name: whois\n",
                "        step_type: pivot\n",
                "        function: util.whois\n",
                "        entity: IpAddress\n",
                "        comment: Get Whois info\n",
                "        params:\n",
                "          column: IPAddress\n",
                "          join: inner\n",
                "      \n",
                "\"\"\""
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 50,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "# Pipeline 1 description\n",
                        "(\n",
                        "    input_df\n",
                        "    # Get IP Type\n",
                        "    .mp_pivot.run(IpAddress.util.ip_type, column='IPAddress', join='inner')\n",
                        "    # Filter to only public IPs\n",
                        "    .query('result == \"Public\"')\n",
                        "    # Get Whois info\n",
                        "    .mp_pivot.run(IpAddress.util.whois, column='IPAddress', join='inner')\n",
                        ")\n"
                    ]
                }
            ],
            "source": [
                "pipelines = list(Pipeline.from_yaml(pipelines_yml))\n",
                "print(pipelines[0].print_pipeline())"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 52,
            "metadata": {},
            "outputs": [
                {
                    "name": "stderr",
                    "output_type": "stream",
                    "text": [
                        "Steps:   0%|          | 0/3 [00:00<?, ?it/s]"
                    ]
                },
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "step = get_ip_type \n",
                        " PipelineExecStep(accessor='mp_pivot.run', pos_params=[], params={'func': <function get_ip_type at 0x000001C163E4E0D0>, 'column': 'IPAddress', 'join': 'inner'}, text=\".mp_pivot.run(IpAddress.util.ip_type, column='IPAddress', join='inner')\", comment='Get IP Type', step_type='pivot')\n",
                        "step = filter_public \n",
                        " PipelineExecStep(accessor='query', pos_params=['result == \"Public\"'], params={}, text='.query(\\'result == \"Public\"\\')', comment='Filter to only public IPs', step_type='pd_accessor')\n",
                        "step = whois \n",
                        " PipelineExecStep(accessor='mp_pivot.run', pos_params=[], params={'func': <function get_whois_df at 0x000001C163E4E040>, 'column': 'IPAddress', 'join': 'inner'}, text=\".mp_pivot.run(IpAddress.util.whois, column='IPAddress', join='inner')\", comment='Get Whois info', step_type='pivot')\n"
                    ]
                },
                {
                    "name": "stderr",
                    "output_type": "stream",
                    "text": [
                        "Steps: 100%|██████████| 3/3 [00:00<00:00,  3.49it/s]\n"
                    ]
                },
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>IPAddress</th>\n",
                            "      <th>ip</th>\n",
                            "      <th>result</th>\n",
                            "      <th>nir</th>\n",
                            "      <th>asn_registry</th>\n",
                            "      <th>asn</th>\n",
                            "      <th>asn_cidr</th>\n",
                            "      <th>asn_country_code</th>\n",
                            "      <th>asn_date</th>\n",
                            "      <th>asn_description</th>\n",
                            "      <th>query</th>\n",
                            "      <th>nets</th>\n",
                            "      <th>raw</th>\n",
                            "      <th>referral</th>\n",
                            "      <th>raw_referral</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>113.190.36.2</td>\n",
                            "      <td>113.190.36.2</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>45899</td>\n",
                            "      <td>113.190.32.0/20</td>\n",
                            "      <td>VN</td>\n",
                            "      <td>2008-11-04</td>\n",
                            "      <td>VNPT-AS-VN VNPT Corp, VN</td>\n",
                            "      <td>113.190.36.2</td>\n",
                            "      <td>[{'cidr': '113.160.0.0/11', 'name': 'VNPT-VN', 'handle': 'PTH13-AP', 'range': '113.160.0.0 - 113...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>118.163.135.17</td>\n",
                            "      <td>118.163.135.17</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>3462</td>\n",
                            "      <td>118.163.0.0/16</td>\n",
                            "      <td>TW</td>\n",
                            "      <td>2007-10-04</td>\n",
                            "      <td>HINET Data Communication Business Group, TW</td>\n",
                            "      <td>118.163.135.17</td>\n",
                            "      <td>[{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>118.163.135.18</td>\n",
                            "      <td>118.163.135.18</td>\n",
                            "      <td>Public</td>\n",
                            "      <td>None</td>\n",
                            "      <td>apnic</td>\n",
                            "      <td>3462</td>\n",
                            "      <td>118.163.0.0/16</td>\n",
                            "      <td>TW</td>\n",
                            "      <td>2007-10-04</td>\n",
                            "      <td>HINET Data Communication Business Group, TW</td>\n",
                            "      <td>118.163.135.18</td>\n",
                            "      <td>[{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "      <td>None</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "        IPAddress              ip  result   nir asn_registry    asn  \\\n",
                            "0    113.190.36.2    113.190.36.2  Public  None        apnic  45899   \n",
                            "1  118.163.135.17  118.163.135.17  Public  None        apnic   3462   \n",
                            "2  118.163.135.18  118.163.135.18  Public  None        apnic   3462   \n",
                            "\n",
                            "          asn_cidr asn_country_code    asn_date  \\\n",
                            "0  113.190.32.0/20               VN  2008-11-04   \n",
                            "1   118.163.0.0/16               TW  2007-10-04   \n",
                            "2   118.163.0.0/16               TW  2007-10-04   \n",
                            "\n",
                            "                               asn_description           query  \\\n",
                            "0                     VNPT-AS-VN VNPT Corp, VN    113.190.36.2   \n",
                            "1  HINET Data Communication Business Group, TW  118.163.135.17   \n",
                            "2  HINET Data Communication Business Group, TW  118.163.135.18   \n",
                            "\n",
                            "                                                                                                  nets  \\\n",
                            "0  [{'cidr': '113.160.0.0/11', 'name': 'VNPT-VN', 'handle': 'PTH13-AP', 'range': '113.160.0.0 - 113...   \n",
                            "1  [{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...   \n",
                            "2  [{'cidr': '118.160.0.0/13', 'name': 'HINET-NET', 'handle': 'AT939-AP', 'range': '118.160.0.0 - 1...   \n",
                            "\n",
                            "    raw referral raw_referral  \n",
                            "0  None     None         None  \n",
                            "1  None     None         None  \n",
                            "2  None     None         None  "
                        ]
                    },
                    "execution_count": 52,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "pipeline1 = pipelines[0]\n",
                "result_df = pipeline1.run(data=suspicious_ips_df)\n",
                "result_df.head(3)"
            ]
        }
    ],
    "metadata": {
        "kernelspec": {
            "display_name": "Python 3.9.7 ('msticpy')",
            "language": "python",
            "name": "python3"
        },
        "language_info": {
            "codemirror_mode": {
                "name": "ipython",
                "version": 3
            },
            "file_extension": ".py",
            "mimetype": "text/x-python",
            "name": "python",
            "nbconvert_exporter": "python",
            "pygments_lexer": "ipython3",
            "version": "3.9.7"
        },
        "vscode": {
            "interpreter": {
                "hash": "0f1a8e166ce5c1ec1911a36e4fdbd34b2f623e2a3442791008b8ac429a1d6070"
            }
        },
        "widgets": {
            "application/vnd.jupyter.widget-state+json": {
                "state": {},
                "version_major": 2,
                "version_minor": 0
            }
        }
    },
    "nbformat": 4,
    "nbformat_minor": 4
}
